#Vulnerabilities

Ghostty's Memory Leak Saga: When Optimizations Backfire

Trends Reporter
2 min read

Mitchell Hashimoto details how a scrollback optimization in Ghostty's terminal caused rare but massive memory leaks up to 37GB, exacerbated by modern CLI tools like Claude Code.

Recent user reports of Ghostty terminal sessions consuming up to 37GB of memory revealed a significant memory leak that had lurked in the software since its 1.0 release. Mitchell Hashimoto's technical breakdown explains how a well-intentioned performance optimization interacted with rare usage patterns to create escalating memory consumption.

At Ghostty's core is the PageList structure—a doubly-linked list managing terminal content through memory pages. Standard-sized pages come from a reusable pool, while larger non-standard pages (used for complex content like emoji clusters) get direct mmap allocations. The critical flaw emerged during scrollback pruning: when reusing pages at the scrollback limit, Ghostty would reset metadata for non-standard pages to standard size without adjusting their actual memory allocation.

This created a dangerous mismatch: when freeing such pages later, Ghostty saw only the reset metadata and returned them to the pool rather than calling munmap. The original large allocation remained unfreed—a classic memory leak. Crucially, this only occurred with non-standard pages, which were historically rare. As Hashimoto notes: "The limited triggering conditions made it fiendishly hard to diagnose."

The leak gained prominence due to changing usage patterns. Tools like Claude Code (an AI coding assistant) frequently produce multi-codepoint grapheme outputs that force non-standard page allocations. Combined with high scrollback activity, this created what Hashimoto calls "the perfect storm." He emphasizes: "This isn't Claude Code's fault—it merely exposed a latent issue."

The fix modifies the scrollback optimization: non-standard pages now get destroyed properly via munmap during pruning, with replacement pages allocated from the standard pool. While some suggested adaptive strategies for non-standard page reuse, Hashimoto opted for simplicity: "Until metrics show otherwise, we maintain that standard pages should be the common case."

Ghostty already employs robust leak detection—Zig's debug allocators, Valgrind in CI, and macOS Instruments—but this leak evaded them due to its specific trigger conditions. Future prevention includes new macOS VM tagging (implementation details) that categorize PageList allocations, plus regression tests replicating the leak scenario.

This incident highlights how optimization trade-offs can manifest unexpectedly under real-world conditions. Hashimoto credits community collaboration for the fix: "User diagnostics around VM region counting pointed us toward PageList, and @grishy's reliable reproduction was invaluable." The solution ships in Ghostty 1.3 this March, closing a chapter on the terminal's largest known memory leak.

Comments

Loading comments...