TL;DR

Ghostty had a memory leak caused by reusing large, non-standard terminal pages while the system thought they were standard-sized, which prevented munmap from being called. A patch that discards non-standard pages during scrollback pruning has been merged and is available in nightly builds and the upcoming 1.3 release.

What happened

Ghostty stores terminal contents in a doubly-linked PageList made of memory "pages." Most pages are a standard size and come from a reusable pool; occasionally the terminal needs larger, non-standard pages allocated directly with mmap. To avoid allocations during heavy scrollback activity, Ghostty reuses the oldest page by moving it to the back of the list and resetting its metadata to the standard size. A logic bug reset only the metadata for a reused page while the underlying mmap allocation remained large. Later code treated that page as a pooled, standard-sized block and did not call munmap, leaving the large allocation orphaned. The condition was rare historically, but some CLI workloads (notably Claude Code) produce many multi-codepoint graphemes and heavy scrollback, which caused many non-standard pages to be created and exposed the leak at scale. The remedy, now merged, prevents reuse of non-standard pages: such pages are destroyed (munmap) during pruning and replaced with fresh standard-sized pages from the pool. The change is in tip/nightly releases and slated for the tagged 1.3 release in March; the fix also adds a regression test.

Why it matters

  • Leaked mmap allocations let Ghostty consume gigabytes over days of uptime, impacting users running long-lived terminal sessions.
  • The bug shows how rare code paths can evade typical leak detectors and only appear under specific workloads.
  • The fix reduces unexpected memory growth for heavy-IO CLI programs that produce many complex graphemes and large scrollback.
  • Adding regression tests and VM tagging improves future detection and verification of memory fixes.

Key facts

  • The leak existed since at least Ghostty 1.0.
  • Ghostty uses a PageList: a doubly-linked list of memory pages storing terminal content.
  • Most pages are a fixed standard size served from a pool; large pages are allocated directly via mmap and must be freed with munmap.
  • An optimization reuses the oldest scrollback page as the newest to avoid allocations during pruning.
  • During reuse the page's metadata was reset to the standard size while the underlying mmap allocation stayed large, so munmap was never called when the page was freed.
  • Heavy outputs (multi-codepoint graphemes) from some CLI apps, notably Claude Code, produced many non-standard pages and exposed the leak.
  • Fix: do not reuse non-standard pages during scrollback pruning; destroy them (munmap) and allocate a fresh standard page from the pool.
  • The fix is merged, available in tip/nightly builds, and will be included in the tagged 1.3 release in March.
  • A regression test that reproduces the leak was added and macOS VM tagging was introduced to make PageList allocations easier to track.

What to watch next

  • The tagged Ghostty 1.3 release due in March (for the official release of this patch).
  • not confirmed in the source: whether the project will adopt adaptive strategies (metrics-driven decisions) for reusing large pages instead of discarding them.
  • Community memory reports and CI results to confirm the fix's effectiveness across different workloads.

Quick glossary

  • PageList: A doubly-linked list structure Ghostty uses to store terminal content across multiple memory pages.
  • mmap: An OS call that maps files or anonymous memory into a process's address space; used here to allocate large, variable-sized terminal pages.
  • munmap: The OS call that releases memory previously allocated with mmap.
  • Scrollback: The portion of terminal history retained so users can scroll back to earlier output.
  • Non-standard page: A PageList memory allocation larger than the standard pooled size; allocated directly with mmap and not reusable via the pool.

Reader FAQ

Was Claude Code responsible for the bug?
No. Claude Code's output exposed a preexisting Ghostty bug by producing conditions that made the leak appear at scale, but it did not cause the defect.

Is the fix available now?
Yes. The fix is merged and available in tip/nightly releases and will be included in the tagged 1.3 release in March.

Will this prevent all memory leaks in Ghostty?
This fixes the largest known PageList leak and includes a regression test; the project continues to run leak detection and monitor reports for other issues.

How was the leak diagnosed?
The maintainer added macOS virtual memory tags to PageList allocations to trace the leak, combined with community-provided reproductions and diagnostics.

MITCHELL HASHIMOTO Finding and Fixing Ghostty's Largest Memory Leak A few months ago, users started reporting that Ghostty was consuming absurd amounts of memory, with one user reporting 37 GB…

Sources

Related posts

By

Leave a Reply

Your email address will not be published. Required fields are marked *