Skip to content

dalsoop/claude-code-memory-leak-fix

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

5 Commits
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

claude-code-memory-leak-fix

Two-tier defense against Claude Code's native heap memory leak.

Who needs this?

If any of these sound familiar, this is for you:

  • Claude Code freezes and takes down your other services
  • htop shows claude eating 10GB, 50GB, 100GB+ of RAM
  • Your server gets OOM-killed during long Claude Code sessions
  • You're running Claude Code on a shared machine (homelab, dev server, CI) and it's starving other processes

You don't need this if: you only use Claude Code for short sessions (under an hour) or on macOS (this is Linux only).

What's the problem?

Claude Code leaks memory. A lot.

During active use (running commands, reading files, writing code), it allocates small 160-byte objects that are never freed. Over a 10-hour session, this adds up to 189GB. This is a known bug with dozens of open GitHub issues but no fix from Anthropic yet.

The leak is in the native C layer (BoringSSL/nghttp2, statically linked into the Bun runtime), so JavaScript-level fixes like --max-old-space-size don't help.

How does the fix work?

Two layers of protection:

Normal use (< 30GB)
  │  Zero overhead. Everything passes through untouched.
  ▼
Tier 1: Malloc Guard (30GB)
  │  Silently pools leaked objects. No interruption.
  │  Your session keeps running normally.
  ▼
Tier 2: Watchdog (60GB)
  │  If tier 1 wasn't enough, kills and restarts the session.
  │  Safety net — should rarely trigger.
Tier Trigger What it does Disruption
Tier 1 30GB LD_PRELOAD intercepts malloc(160), pools leaked objects None
Tier 2 60GB Watchdog restarts the session Session restart

Install

Requirements: Linux, GCC, glibc, make

git clone https://github.com/dalsoop/claude-code-memory-leak-fix.git
cd claude-code-memory-leak-fix
make
sudo make install

This installs two things:

  • /usr/local/lib/claude_malloc_guard.so — the malloc interceptor
  • /usr/local/bin/claude-safe — drop-in wrapper script

Usage

Just use claude-safe instead of claude. All arguments are passed through:

claude-safe                    # interactive session
claude-safe -p "do something"  # one-shot prompt
claude-safe --model sonnet     # any claude flag works

Check if it's working

# Send SIGUSR1 to dump stats
kill -USR1 $(pgrep -n claude)

# Read the log
cat /tmp/claude_malloc_guard.log

Example output:

[malloc-guard] 160B alloc=17 free=0 live=17 pool_hit=0 guard=standby
  • alloc — total 160-byte allocations
  • free — how many were freed (spoiler: 0)
  • guard=standby — tier 1 hasn't activated yet (under 10GB)
  • guard=ACTIVE — tier 1 is pooling objects

Adjust thresholds

# Lower the watchdog threshold to 8GB
CLAUDE_WATCHDOG_THRESHOLD_MB=8192 claude-safe

# Check more frequently (every 10 seconds)
CLAUDE_WATCHDOG_INTERVAL=10 claude-safe
Variable Default Description
CLAUDE_MALLOC_GUARD_LIB /usr/local/lib/claude_malloc_guard.so Path to guard .so
CLAUDE_WATCHDOG_THRESHOLD_MB 61440 (60GB) Tier 2 restart threshold
CLAUDE_WATCHDOG_INTERVAL 30 Watchdog check interval (seconds)

Uninstall

cd claude-code-memory-leak-fix
sudo make uninstall

How we found this

Full technical analysis: anthropics/claude-code#36956

Summary:

  • Dumped /proc/pid/mem of a 189GB claude process
  • Found 1.15 billion identical 176-byte malloc chunks filling the heap
  • Confirmed Claude Code is Bun (not Node.js) with dual allocator (mimalloc + glibc)
  • Leak is in glibc malloc's [heap] region — static-linked C libraries (BoringSSL, nghttp2) allocate but never free
  • Verified with our malloc tracer: free() is literally never called for these objects

FAQ

Q: Will this break Claude Code? A: No. Below 10GB it does nothing (just counts). Above 10GB it only touches 160-byte allocations. Everything else passes through to the original malloc.

Q: Does it work on macOS? A: No. This uses LD_PRELOAD which is Linux-specific. macOS would need DYLD_INSERT_LIBRARIES with a different approach.

Q: What if Anthropic fixes the leak? A: Then the guard never activates (stays in standby) and has zero overhead. You can leave it installed or uninstall it.

Q: What if the leaked object size changes in a future version? A: Tier 1 (malloc guard) won't catch it, but Tier 2 (watchdog) will still restart the session before memory gets out of control.

License

MIT

About

Fix for Claude Code memory leak — LD_PRELOAD guard that caps runaway heap growth (189GB+ over 10h). Bun runtime leaks 160-byte objects that are never freed.

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors