Runaway anonymous-memory growth (~14.5 GiB in ~5 min) kills the CLI — reproduces on BOTH native (Bun/JSC) and npm (Node/V8) installs

Status Closed — not planned
Reported on v2.1.220
Maintainer reply None cached
Activity 3 comments · opened Aug 12, 2026 · closed Aug 23, 2026

Summary

Since around 2026-08-11 the claude process has repeatedly grown its anonymous memory
from normal (~1 GiB) to ~14.5 GiB within about five minutes, until the kernel OOM-kills it
(24 GiB host) or the machine becomes unusable through swap thrashing (4 GiB host).

This is not a slow leak: cloud monitoring graphs show a near-vertical ramp, not a gradual climb.

The same failure occurs on two different hosts with two different install methods and two
different JS runtimes
, which suggests the cause is in application-level JS, not in the runtime.

Impact

  • Host A (24 GiB): 3 OOM kills, session lost each time.
  • Host B (4 GiB): after swap was raised to 12 GiB the process no longer OOMs — instead it

saturates disk I/O and the host stops responding, requiring 5+ hard reboots.
(Raising swap made the failure worse: a fast kill became a multi-minute hang.)

Environment

| | Host A | Host B |
|---|---|---|
| Install | native binary (~/.local/share/claude/versions/<ver>) | npm @anthropic-ai/claude-code |
| Runtime | Bun 1.4.0 / JavaScriptCore | Node v24.16.0 / V8 |
| Versions seen failing | 2.1.220, 2.1.227 | 2.1.x (current: 2.1.228) |
| OS / kernel | Ubuntu 24.04.4 LTS · 6.17.0-1019-oracle | Ubuntu (VM) |
| Arch | aarch64 | x86_64 |
| CPU / RAM / swap | 4 cores / 24 GiB / 4 GiB | 2 cores / 3.6 GiB / 6–12 GiB |

Evidence — kernel OOM records (Host A)

Aug 11 17:46:24  Out of memory: Killed process 788148  (2.1.220)
  total-vm:17060496kB  anon-rss:14816000kB  file-rss:1728kB  pgtables:29396kB

Aug 11 22:33:48  Out of memory: Killed process 1777558 (2.1.227)
  total-vm:17088908kB  anon-rss:15127040kB  file-rss:1648kB  pgtables:29920kB

Aug 13 02:41:23  Out of memory: Killed process 3210530 (2.1.227)
  total-vm:17088972kB  anon-rss:15241344kB  file-rss:1328kB  pgtables:30176kB

Two details we think are diagnostically useful:

  1. 🔴 total-vm is nearly identical across all three events

(17,060,496 / 17,088,908 / 17,088,972 kB — spread 0.167 %),
across two different versions and three different sessions.
Such tight clustering suggests a deterministic allocation path reaching a fixed ceiling,
not stochastic leakage.

  1. anon-rss is 99.99 % of RSS (file-rss ≈ 1.3 MB).

The growth is pure heap/anonymous memory — not mmap'd files or page cache.

The user cgroup slice peaked at 18,694,496,256 bytes (17.4 GiB);
memory.max was unset (max), so nothing capped it.

What we ruled out

| Hypothesis | Ruled out by |
|---|---|
| Slow leak in long sessions (the class fixed in 2.1.221) | Monitoring graphs show ~5-minute vertical ramp, not gradual growth |
| Runtime heap-limit misconfiguration (V8 / JSC) | Reproduces on both Bun/JSC and Node/V8 |
| High workflow / subagent fan-out | The 2026-08-13 event occurred with no workflow running |
| Background process / cron / OS | Host B ran 3 days with claude not started and had zero incidents |
| MCP servers, hooks, plugins, statusLine | None configured on Host A (hooks/mcpServers/plugins all empty) |
| File-backed memory | file-rss ≈ 1.3 MB vs anon-rss ≈ 14.5 GiB |

What we could not determine

We could not identify which allocation path is responsible.
A 10-second RSS sampler was deployed on Host B and did capture a burst, but it only confirmed
"the claude process is the one growing" — it cannot show what is being allocated.
Capturing an allocation stack would require attaching perf/bpftrace to a production session,
which we have not done.

Possibly relevant context

  • Both hosts ran the same kinds of workloads for 1–2 months without any incident;

the failures began only in the last few days.

  • Session transcripts on Host A are relatively large (largest active session JSONL ≈ 42 MB).
  • Host A is aarch64; Host B is x86_64 — so this is not architecture-specific.

Questions

  1. Is there a known code path that can allocate unbounded anonymous memory

(e.g. buffering a large tool result, transcript re-parse, or an unbounded accumulation)?

  1. Is there any supported way to cap the CLI's heap so it fails fast instead of taking the host down?

(NODE_OPTIONS=--max-old-space-size appears not to apply to the native Bun build.)

  1. Would a heap snapshot be useful, and is there a supported way to trigger one from a running session?

We are happy to run a targeted diagnostic if you can suggest one — we can reproduce,
though not yet on demand.

---

View original on GitHub ↗

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