Memory leak: 2.92 GB external ArrayBuffers after 34 min session (v2.1.72)

Resolved 💬 6 comments Opened Mar 11, 2026 by RaiAnsar Closed Apr 9, 2026

Description

Claude Code leaks ~490 MB/hour of external (native) ArrayBuffer memory. A 34-minute session accumulated 3.39 GB of external memory (2.92 GB in ArrayBuffers), while the V8 heap itself remained healthy at ~126 MB.

The memory is invisible to V8 heap snapshots — it lives in native/external allocations tracked by V8 but not captured in .heapsnapshot files. This points to a leak in the HTTP streaming layer (likely undici response body buffers not being freed).

Environment

  • Claude Code version: 2.1.72
  • Node.js version: v24.3.0
  • Platform: macOS Darwin 25.3.0 (Apple Silicon)
  • Model: claude-opus-4-6

Reproduction

  1. Start a Claude Code session
  2. Use it normally (chat, tool calls, web fetches, file reads)
  3. After ~30 minutes, run /heapdump
  4. Observe external memory growing at ~490 MB/hour

Diagnostics Data

From the diagnostics JSON (/heapdump output):

{
  "uptimeSeconds": 2033.87,
  "memoryUsage": {
    "heapUsed": 3511037332,
    "heapTotal": 136690688,
    "external": 3392535811,
    "arrayBuffers": 2915585335,
    "rss": 290684928
  },
  "memoryGrowthRate": {
    "bytesPerSecond": 142922.24,
    "mbPerHour": 490.68
  },
  "v8HeapStats": {
    "heapSizeLimit": 12440698880,
    "mallocedMemory": 3511299731,
    "peakMallocedMemory": 1244069888,
    "detachedContexts": 0,
    "nativeContexts": 1
  },
  "resourceUsage": {
    "maxRSS": 1273927565312
  }
}

Heap Snapshot Analysis

The V8 heap snapshot (76 MB serialized) shows the JS heap is healthy at ~126 MB. The top consumers are:

| Category | Size | Notes |
|---|---|---|
| [object] Object | 20.1 MB | 419K objects — normal |
| [object] ArrayBuffer | 19.0 MB | 8 ArrayBuffers (V8-managed, tiny vs the 2.92 GB external) |
| [code] FunctionCodeBlock | 14.0 MB | 4,261 blocks — normal |
| [native] Blob | 9.8 MB | 7 Blobs retained by a single Array(6) |
| [closure] Function | 4.3 MB | 136K closures — normal |

The 16 MB ArrayBuffer is retained by WebAssembly.Memory (expected — likely argon2/crypto).

Additional observations

  • Duplicated skill definitions: Every skill appears twice in memory (~800 KB wasted)
  • Duplicated conversation context: 6 copies of the same drizzle/postgres schema (~650 KB)
  • Base64 PNG screenshots: 2x 582 KB each (1.1 MB)
  • maxRSS reports 1.18 TB — clearly a Node v24.3.0 reporting bug on macOS (ru_maxrss units issue)

Root Cause Hypothesis

The 2.92 GB of external ArrayBuffers are not captured in the heap snapshot (V8 limitation for external/native memory). The most likely source is undici HTTP response body buffers from Anthropic API streaming responses not being garbage collected. The growth is linear (~490 MB/hour), suggesting each API response's buffer is retained indefinitely.

Workaround

Restart Claude Code sessions every 1-2 hours to reclaim memory.

View original on GitHub ↗

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