Memory leak: BytesInternalReadableStreamSource ArrayBuffer accumulation (3.3GB in 59s)

Resolved 💬 5 comments Opened Mar 12, 2026 by AsgerGotved Closed Apr 24, 2026

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 external memory 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:

  1. The V8 heap is tiny (63 MB) but external memory is 3.75 GB
  2. The largest heap objects are stream internals (BytesInternalReadableStreamSource, Blob)
  3. 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 /heapdump when the high memory warning appears to capture diagnostics
  • Monitor with docker stats or 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).

View original on GitHub ↗

This issue has 5 comments on GitHub. Read the full discussion on GitHub ↗