You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
limux-host grows without bound at roughly 2.7 GB/day under normal use. After 5 days 11 hours of uptime the process holds 15.07 GB committed. Sampling the memory shows the bytes are RGBA terminal framebuffers — 88–98% of the two dominant regions is the repeating word 282c34ff, which is #282c34 (the terminal background) at full alpha.
This is not#137. That issue was Ghostty surfaces outliving their panes, and the fix in #138 works correctly here: thread trios stay balanced (6 renderer / 6 io / 6 io-reader against 6 live surfaces) for the whole run, and closing panes tears the surfaces down cleanly. Framebuffers leak anyway.
Environment
limux
0.1.24 (dpkg), binary built 2026-08-09 20:15
libghostty
fork bvolpato/ghostty @ 81ab8ff (the submodule pin at the v0.1.24 build)
kernel
7.0.0-28-generic
hardware
62 GB RAM, 63 GB swap, NVIDIA GPU, GTK4
workload
4 workspaces, 6 surfaces, several long-running CLI agent sessions
RSS alone hides this completely. At the measurement above the process shows under 300 MB resident while holding 15 GB. Everything is paged out. Any monitoring based on VmRSS will report a healthy process. VmRSS + VmSwap is the number that matters.
Growth is activity-driven. An 8-hour idle window showed committed memory flat to within 5 MB. Growth events correlate with whichever surface is focused during use.
Sampled with a plain pread of /proc/<pid>/mem (no ptrace attach, so the process is never stopped), 4 MB each at head, middle and tail.
Anonymous region, 7821 MB:
sample 282c34ff longest run printable
head 97.8% 0.63 MB 74.0%
mid 88.1% 0.52 MB 73.9%
tail 94.4% 0.49 MB 71.6%
93.4% average across 12 MB sampled. Extrapolated over the region that is ~7.3 GB of background pixels, roughly 200 framebuffers at the ~40 MB size of a 4877x2050 RGBA surface.
[heap], 5745 MB:
head 53.5% 00000000, 68.3% zero bytes allocator free space
mid 89.7% 282c34ff framebuffers, RGBA
tail 78.3% 342c28ff framebuffers, BGRA
Note the tail: 342c28ff is the same colour with the channel order reversed. Two pixel layouts are present in the leaked buffers, which suggests two producers — or a format-conversion staging buffer whose output is also retained.
The remaining top words in every framebuffer sample are UI greys (888888ff, 373737ff, 4b4d51ff, 9c9d9eff) and, in the BGRA tail, greens (002802ff, 004704ff). These are rendered screens, not blank allocations.
Small amounts of limux IPC JSON are interleaved:
"tion.create","params":{"body":"Claude needs your permission","subtitle
Negligible by volume against 93% pixels, but it confirms these regions are general allocation arenas rather than a dedicated framebuffer pool.
Ruled out
Each tested on a freshly restarted process where a step would have been obvious:
Scrollback. limux never sets scrollback-limit. Setting it to 5 MB in ~/.config/ghostty/config slowed the rate by roughly 40% but did not stop it. Streaming 54 MB of text through a terminal added 48 MB and then stayed flat for three minutes.
Layout resize. Three pane create/close cycles returned committed memory to baseline every time.
Workspace switching. Eight switches produced no growth.
0.1.23 hit the same symptom via #137 and was OOM-killed at 21.5 GB anon-rss (journalctl -k, 2026-08-10 22:53). A capture on 2026-08-12 from that build found the identical 282c34ff pattern at 79% of 252 MB sampled. The #138 fix removed the orphaned-surface mechanism but not the framebuffer retention.
Not tested against main
main has moved well past v0.1.24. PR #145 (merged 2026-08-16) upgrades the embedded Ghostty from 81ab8ff to 1a89efa and switches the fork from am-will/ghostty to bvolpato/ghostty — 69 files and roughly +15,400 lines across src/renderer and src/apprt, plus a terminal memory subsystem that does not exist in the released build (src/terminal/mem.zig and src/terminal/compress.zig are absent at 81ab8ff and present at 1a89efa).
Everything above was measured on the released v0.1.24 binary. I have not built or run main. No merge since v0.1.24 mentions memory or buffer lifetime, and the new frame lifetime work (frame_lease.zig, external_frame.zig, CompletionLifetime.zig) is Metal/IOSurface rather than the OpenGL path this report covers, so I would not assume the upgrade addresses this. If you already know it does, say so and I will retest against main rather than take up your time.
Reproduction
Run 0.1.24 with several terminal surfaces under sustained interactive load for a day or more on a large window, then compare VmRSS + VmSwap against uptime. Sample the largest anonymous mapping for the repeating background colour.
Scripts used are attachable: a step watcher that logs new mappings with the focused surface, and the memory sampler described above.
Summary
limux-hostgrows without bound at roughly 2.7 GB/day under normal use. After 5 days 11 hours of uptime the process holds 15.07 GB committed. Sampling the memory shows the bytes are RGBA terminal framebuffers — 88–98% of the two dominant regions is the repeating word282c34ff, which is#282c34(the terminal background) at full alpha.This is not #137. That issue was Ghostty surfaces outliving their panes, and the fix in #138 works correctly here: thread trios stay balanced (6 renderer / 6 io / 6 io-reader against 6 live surfaces) for the whole run, and closing panes tears the surfaces down cleanly. Framebuffers leak anyway.
Environment
dpkg), binary built 2026-08-09 20:15bvolpato/ghostty@81ab8ff(the submodule pin at the v0.1.24 build)Measurements
Fresh process started 2026-08-18 11:09 at 348 MB.
RSS alone hides this completely. At the measurement above the process shows under 300 MB resident while holding 15 GB. Everything is paged out. Any monitoring based on
VmRSSwill report a healthy process.VmRSS + VmSwapis the number that matters.Growth is activity-driven. An 8-hour idle window showed committed memory flat to within 5 MB. Growth events correlate with whichever surface is focused during use.
The leak is one ever-growing region
Two mappings hold 13.7 of the 15.07 GB:
The anonymous region grows by
mremap, so its start address moves. Sizes recorded across the run, in order, never decreasing:Byte-level evidence
Sampled with a plain
preadof/proc/<pid>/mem(no ptrace attach, so the process is never stopped), 4 MB each at head, middle and tail.Anonymous region, 7821 MB:
93.4% average across 12 MB sampled. Extrapolated over the region that is ~7.3 GB of background pixels, roughly 200 framebuffers at the ~40 MB size of a 4877x2050 RGBA surface.
[heap], 5745 MB:Note the tail:
342c28ffis the same colour with the channel order reversed. Two pixel layouts are present in the leaked buffers, which suggests two producers — or a format-conversion staging buffer whose output is also retained.The remaining top words in every framebuffer sample are UI greys (
888888ff,373737ff,4b4d51ff,9c9d9eff) and, in the BGRA tail, greens (002802ff,004704ff). These are rendered screens, not blank allocations.Small amounts of limux IPC JSON are interleaved:
Negligible by volume against 93% pixels, but it confirms these regions are general allocation arenas rather than a dedicated framebuffer pool.
Ruled out
Each tested on a freshly restarted process where a step would have been obvious:
scrollback-limit. Setting it to 5 MB in~/.config/ghostty/configslowed the rate by roughly 40% but did not stop it. Streaming 54 MB of text through a terminal added 48 MB and then stayed flat for three minutes.Prior history on this machine
0.1.23 hit the same symptom via #137 and was OOM-killed at 21.5 GB anon-rss (
journalctl -k, 2026-08-10 22:53). A capture on 2026-08-12 from that build found the identical282c34ffpattern at 79% of 252 MB sampled. The #138 fix removed the orphaned-surface mechanism but not the framebuffer retention.Not tested against
mainmainhas moved well past v0.1.24. PR #145 (merged 2026-08-16) upgrades the embedded Ghostty from81ab8ffto1a89efaand switches the fork fromam-will/ghosttytobvolpato/ghostty— 69 files and roughly +15,400 lines acrosssrc/rendererandsrc/apprt, plus a terminal memory subsystem that does not exist in the released build (src/terminal/mem.zigandsrc/terminal/compress.zigare absent at81ab8ffand present at1a89efa).Everything above was measured on the released v0.1.24 binary. I have not built or run
main. No merge since v0.1.24 mentions memory or buffer lifetime, and the new frame lifetime work (frame_lease.zig,external_frame.zig,CompletionLifetime.zig) is Metal/IOSurface rather than the OpenGL path this report covers, so I would not assume the upgrade addresses this. If you already know it does, say so and I will retest againstmainrather than take up your time.Reproduction
Run 0.1.24 with several terminal surfaces under sustained interactive load for a day or more on a large window, then compare
VmRSS + VmSwapagainst uptime. Sample the largest anonymous mapping for the repeating background colour.Scripts used are attachable: a step watcher that logs new mappings with the focused surface, and the memory sampler described above.