Memory leak: BytesInternalReadableStreamSource ArrayBuffer accumulation (3.3GB in 59s)
Summary
Claude Code accumulates ~54 MB/sec of ArrayBuffer memory from the moment it starts, reaching 3.3 GB within 59 seconds on a fresh session. The leak is intermittent — some startups are fine, others immediately balloon.
Heapdump analysis points to BytesInternalReadableStreamSource (the undici/fetch streaming internals) not releasing response body buffers.
Environment
- Claude Code: 2.1.73 (also observed on 2.1.74)
- Node.js: v24.3.0 (bundled), also observed with system v24.12.0
- Platform: Linux (Docker container on Windows 11), also reproduced on native Windows
- No MCP servers configured in the affected container session
Diagnostics
From /heapdump after 59 seconds on a brand new session (no user interaction yet):
{
"uptimeSeconds": 58.82,
"memoryUsage": {
"heapUsed": 3794153907,
"heapTotal": 63706112,
"external": 3746021251,
"arrayBuffers": 3343221740,
"rss": 3204550656
},
"memoryGrowthRate": {
"bytesPerSecond": 54481849,
"mbPerHour": 187048
}
}
Key observations:
- V8 heap is only 63 MB — the JavaScript heap itself is fine
- 3.34 GB is in
arrayBuffers(native/external memory) - 3.75 GB in
externalmemory total - Growth rate: ~54 MB/sec
Heapdump analysis
Parsing the V8 heap snapshot shows:
Objects > 1MB:
16.8 MB - object: BytesInternalReadableStreamSource
16.0 MB - object: ArrayBuffer
3.7 MB - native: Blob
2.4 MB - native: Blob
1.7 MB - native: Blob
1.3 MB - native: Blob
BytesInternalReadableStreamSource is Node.js/undici's internal class backing fetch() response ReadableStreams. The ArrayBuffers are the streaming response body chunks accumulating in native memory without being released.
Likely cause
The streaming fetch() connection to the Anthropic API appears to not properly consume or release response body buffers in some sessions. Since:
- The V8 heap is tiny (63 MB) but external memory is 3.75 GB
- The largest heap objects are stream internals (
BytesInternalReadableStreamSource,Blob) - The leak is intermittent (some startups are fine)
This suggests a race condition during stream setup where the consumer doesn't attach properly, causing incoming data chunks to accumulate as unreleased native ArrayBuffers.
Reproduction
- Start Claude Code in a clean environment (fresh session, no MCP servers)
- The leak appears intermittently — roughly 1 in 3 startups in our testing
- Run
/heapdumpwhen the high memory warning appears to capture diagnostics - Monitor with
docker statsor Task Manager — affected sessions grow at ~54 MB/sec from the first second
Workaround
Restart Claude Code. Unaffected sessions stay at normal memory levels (~400-600 MB).
This issue has 5 comments on GitHub. Read the full discussion on GitHub ↗