[BUG] Memory leak: ArrayBuffer accumulation in long-running sessions (~205 MB/hour)

Resolved 💬 3 comments Opened Mar 11, 2026 by LtSnuggie Closed Mar 15, 2026

Preflight Checklist

  • [x] I have searched existing issues and this hasn't been reported yet
  • [x] This is a single bug report (please file separate reports for different bugs)
  • [x] I am using the latest version of Claude Code

What's Wrong?

Summary

Long-running Claude Code sessions accumulate unreleased ArrayBuffer objects, growing heap usage at ~205 MB/hour. After 8.3 hours of normal use, the process held 27.6 GB in ArrayBuffers (57,971 instances) — 99.5% of total heap.

Environment

  • Claude Code version: 2.1.72
  • Node version: v24.3.0
  • Platform: macOS (Darwin)
  • Trigger: Manual heap snapshot after noticing system slowdown

Evidence from heap snapshot

Memory breakdown

| Metric | Value |
|---|---|
| Heap used | 27.7 GB |
| ArrayBuffers | 27.6 GB (57,971 instances) |
| External memory | 28.2 GB |
| RSS | 1.7 GB |
| Growth rate | 204.7 MB/hour |
| Session uptime | 8.3 hours |

Largest individual objects

| Size | Type | Name |
|---|---|---|
| 181 MB | native | Response |
| 181 MB | native | Response |
| 181 MB | native | Response |
| 16 MB | object | ArrayBuffer |
| 3.7 MB | object | ArrayBuffer |
| 3.2 MB | native | Blob |
| 2.4 MB | native | Blob |
| 1.2 MB | object | BytesInternalReadableStreamSource |

Key class-level aggregation

| Class | Total size | Instance count |
|---|---|---|
| ArrayBuffer | 27,615 MB | 57,971 |
| Uint8Array | 4.8 MB | 58,623 |
| BytesInternalReadableStreamSource | 2.6 MB | 4 |

Root cause analysis

The accumulation pattern points to HTTP response bodies from the Claude API not being fully released after consumption:

  1. 3 Response objects at 181 MB each remain in the heap as native references — these are fetch Response objects whose backing memory hasn't been freed.
  2. 4 BytesInternalReadableStreamSource instances (2.6 MB total) indicate readable streams that were opened but whose underlying buffers were never fully drained or cancelled. This is the internal stream wrapper — its presence suggests the streaming response path (token-by-token output) may not be finalizing the stream's buffer pool.
  3. 57,971 ArrayBuffer instances with 58,623 Uint8Array views — nearly 1:1 ratio — suggests each API response chunk creates a buffer that is never GC'd because something retains a reference to either the Response, the stream, or a Uint8Array view.

In Node/Bun, if a Response body is not fully consumed (via .json(), .text(), .arrayBuffer(), or .body.cancel()), the runtime retains the entire response buffer. For streaming responses, if the ReadableStream is read but the underlying source isn't properly closed, the internal buffers accumulate.

The RSS (1.7 GB) being far lower than heap used (27.7 GB) indicates the OS has compressed/paged most of this memory, which delays the visible impact but progressively degrades system performance.

Diagnostics JSON (built-in analysis)

The built-in diagnostics flagged:

{
  "potentialLeaks": [
    "High memory growth rate: 204.7 MB/hour"
  ],
  "recommendation": "WARNING: 1 potential leak indicator(s) found. See potentialLeaks array."
}

Reproduction

This occurred during a normal interactive session (~8 hours, moderate usage with multiple conversations involving code search, file edits, and tool use). No unusual activity — just sustained use over a workday.

Suggested investigation areas

  1. The streaming response handler — ensure ReadableStream bodies from API fetch calls are fully consumed and the stream is closed/cancelled after use
  2. Check if Response objects from the Anthropic API client are being held in closures, caches, or event listeners after their content has been processed
  3. Verify that AbortController signals properly release associated response buffers when conversations are cancelled or compacted

Workaround

Restarting Claude Code periodically (every few hours) keeps memory manageable.

What Should Happen?

When Claude Code runs for extended periods (8+ hours), memory usage should remain stable — not grow linearly at 205 MB/hour. Response bodies from API calls should be fully consumed and
released after processing, and streaming responses should properly finalize their underlying buffer pools so ArrayBuffers are eligible for garbage collection.

dc6cad05-9754-4931-9a49-b7346673fba8-diagnostics.json

Error Messages/Logs

Steps to Reproduce

  1. Start a Claude Code interactive session (claude in terminal)
  2. Use it normally over a workday — conversations involving code search, file edits, tool use, context compaction
  3. After ~8 hours, run /heapdump (or observe system memory pressure via Activity Monitor)
  4. Heap snapshot shows ~27.6 GB retained in 57,971 ArrayBuffer instances, with 3 unreleased Response objects at 181 MB each

Claude Model

Opus

Is this a regression?

I don't know

Last Working Version

_No response_

Claude Code Version

2.1.72

Platform

Anthropic API

Operating System

macOS

Terminal/Shell

Other

Additional Information

Using Ghostty

View original on GitHub ↗

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