Two-tier defense against Claude Code's native heap memory leak.
If any of these sound familiar, this is for you:
- Claude Code freezes and takes down your other services
htopshows 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).
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.
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 |
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 installThis installs two things:
/usr/local/lib/claude_malloc_guard.so— the malloc interceptor/usr/local/bin/claude-safe— drop-in wrapper script
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# Send SIGUSR1 to dump stats
kill -USR1 $(pgrep -n claude)
# Read the log
cat /tmp/claude_malloc_guard.logExample output:
[malloc-guard] 160B alloc=17 free=0 live=17 pool_hit=0 guard=standby
alloc— total 160-byte allocationsfree— how many were freed (spoiler: 0)guard=standby— tier 1 hasn't activated yet (under 10GB)guard=ACTIVE— tier 1 is pooling objects
# 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) |
cd claude-code-memory-leak-fix
sudo make uninstallFull technical analysis: anthropics/claude-code#36956
Summary:
- Dumped
/proc/pid/memof 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
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.
MIT