[BUG] Runaway node fork storm (~43 procs/sec) from claude-code sessions exhausts 48GB RAM → 3 macOS kernel panics in 24h (forensic data included)
Summary
claude-code sessions on macOS trigger runaway node process fork storms (up to 43 new processes/second), exhausting 48 GB of RAM within minutes and causing 3 macOS kernel panics (watchdog timeout) within 24 hours. I have detailed forensic data from JetsamEvent reports, disk-writes resource diagnostics, and a 10-second-interval monitoring log that captured a storm in real time.
This appears to combine two known issues — MCP/child processes never reaped on session end (#33947, #40667, #36616) and unbounded process multiplication across concurrent sessions (#45880) — but escalates them to full kernel panics, with hard numbers.
Environment
- macOS 26.5.2 (25F84), MacBook Pro Mac17,8 (Apple Silicon T6050, 18 cores, 48 GB RAM)
- claude-code 2.1.217 (bundled with Claude desktop 1.24012.1; also used inside cmux 0.62.2→0.64.20)
- node v25.8.1 (homebrew)
- ~10 stdio MCP servers configured (npx-based), later reduced as mitigation
- Workload: agentic editing on a Next.js 16 project (subagent-driven), i.e. frequent file edits while
nextbuild/dev tooling spawns SWC workers
Incident timeline (all 2026-07, KST)
| When | Event |
|---|---|
| 07-19 08:19 | JetsamEvent — largest: Virtualization VM; Claude + node pressure |
| 07-22 06:18 | JetsamEvent + WindowServer watchdog timeout + shutdown stall |
| 07-22 08:18 | Kernel panic (watchdog) after OOM |
| 07-23 05:52 | JetsamEvent: 2,760 node processes, 111 GB combined rpages, inside a cmux-led coalition running claude-code 2.1.217. One node held 12,800 open fds (cpuTime 107 s). Free memory 261 MB at capture |
| 07-23 05:56 | Kernel panic (watchdog, wdog boot fault) |
| 07-23 07:24 | Storm captured live by my 10s watchdog log (below). Heaviest process: next-swc.darwin-arm64.node under coalition com.anthropic.claudefordesktop; single node dirtied 8.59 GB file-backed memory over 1,842 s (disk-writes diag) |
| 07-23 07:29 | Kernel panic (watchdog timeout: "no checkins from monitoring") |
Real-time capture of the storm (10s polling)
07:24:35 node=5 free=93%
07:24:55 node=867 free=63% <- +862 processes in 20 seconds (~43/sec)
07:25:18 node=2149 free=30% <- kill attempts could not keep up
(no further log entries possible — system unresponsive)
07:29 kernel panic, forced reboot
Notable: my cleanup script SIGKILLed matching nodes twice during the storm; respawn outpaced the kills, and once memory was exhausted the script itself could no longer be scheduled.
Evidence of the two contributing defects
- Orphaned children: after sessions end, npx-launched MCP
nodeprocesses remain alive reparented to launchd (PPID=1). Observed repeatedly; matches #33947 / #40667. - Unbounded multiplication: each claude session spawns its own full set of stdio MCP servers; concurrent sessions/subagents multiply them with no global cap or memory ceiling; matches #28860 / #45880. Combined with an agentic edit loop on a Next.js project (SWC/compile workers respawning per rebuild), spawn rate reached ~43 procs/sec.
Impact
Three full kernel panics (watchdog) in 24 h; total data-loss risk for anything unsaved; machine unusable during storms. This is not graceful degradation — macOS's Jetsam could not contain it.
Mitigations I had to apply (workarounds, not fixes)
kern.maxprocperuidlowered 8000 → 800 via LaunchDaemon (kernel-enforced hard stop)- 10-second watchdog LaunchAgent that SIGKILLs node/bun/next workers on count/rate triggers
- Reduced MCP server count; project CLAUDE.md rules forbidding watch-mode tools in sessions
Requests
- Reap the entire process group (MCP servers, spawned build tools) reliably on session/subagent end — e.g.
killpgon exit, PID tracking, or launching children in their own process group with cleanup. - A global cap / rate limit on child process spawning per session, and a memory ceiling.
- Share MCP server processes across concurrent sessions (#28860) or at least de-duplicate identical stdio servers.
I can provide the full JetsamEvent .ips files, the disk-writes diag, and my monitoring logs on request.
3 Comments
Independent reproduction on macOS with a very similar fork pattern.
Environment
Mac14,9, Apple Silicon, 16 GB RAMJetsam evidence
The incident was captured in
JetsamEvent-2026-08-11-235729.ips:nodein the Visual Studio Code coalitionnoderpages: 1,725,565, approximately 26,961 MiB on this systemAn earlier Jetsam capture on the same machine contained 1,137 node processes and approximately 29 GB attributed to the same pattern.
Trigger candidate and mitigation
context-modewas the only enabled local Node-based MCP plugin in this setup and had registered hooks for SessionStart, UserPromptSubmit, PreToolUse, PostToolUse, and PreCompact. It had been disabled after the first incident but was later enabled again while older Claude sessions were still alive. The second storm occurred after that.This correlation does not prove that context-mode itself is the root cause; Claude Code still needs a process-group cleanup and global spawn cap so a plugin/MCP failure cannot exhaust the whole machine.
Mitigations currently preventing recurrence:
After applying those mitigations, a real terminal invocation completed successfully, left zero matching Node processes behind, and VS Code remained stable at 12 processes and roughly 1.7–1.8 GB RSS.
I can provide sanitized aggregate data from both Jetsam reports or run additional targeted diagnostics if maintainers need a specific signal.
Correction/follow-up to my report above: the newest recurrence produced enough local evidence to identify a different immediate trigger.
In this incident Claude Code invoked
npx next dev -p 3100for a Next.js 16.2.12 project. Turbopack became ready, then the first page compilation spawned hundreds of Node children. The macOS Jetsam report captured 782 Node processes, 777 in the VS Code/devserver coalition. Switching the same project tonext dev --webpackproduced five successful requests while remaining at 4 total Node processes (~67 MB RSS).So this particular recurrence was a Next.js/Turbopack worker-respawn storm launched from a Claude session, not evidence that the Claude binary itself forked the children. I reported the detailed reproduction to the related Next.js issue: https://github.com/vercel/next.js/issues/92978#issuecomment-5259697796
I am leaving the earlier Claude report in place because the original incidents did not preserve command lines, but this latest event should not be counted as an independent Claude-core reproduction.
This has been fixed in Turbopack - I would recommend updating to Next.js 16.3. Please see https://github.com/vercel/next.js/issues/92978#issuecomment-5110231290 and https://github.com/vercel/next.js/pull/96159.
I believe this can be closed?