[BUG] Memory leak: ArrayBuffer accumulation in long-running sessions (~205 MB/hour)
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:
- 3
Responseobjects at 181 MB each remain in the heap as native references — these are fetchResponseobjects whose backing memory hasn't been freed. - 4
BytesInternalReadableStreamSourceinstances (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. - 57,971
ArrayBufferinstances with 58,623Uint8Arrayviews — nearly 1:1 ratio — suggests each API response chunk creates a buffer that is never GC'd because something retains a reference to either theResponse, the stream, or aUint8Arrayview.
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
- The streaming response handler — ensure
ReadableStreambodies from API fetch calls are fully consumed and the stream is closed/cancelled after use - Check if
Responseobjects from the Anthropic API client are being held in closures, caches, or event listeners after their content has been processed - Verify that
AbortControllersignals 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
- Start a Claude Code interactive session (claude in terminal)
- Use it normally over a workday — conversations involving code search, file edits, tool use, context compaction
- After ~8 hours, run /heapdump (or observe system memory pressure via Activity Monitor)
- 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
This issue has 3 comments on GitHub. Read the full discussion on GitHub ↗