[BUG] Forked/resumed sessions and per-session MCP servers leak indefinitely, degrading performance over days
What's Wrong?
Over a stretch of continuous multi-session use, Claude Code has become noticeably laggy — particularly tsc and shell command execution — compared to how the same setup ran previously. Investigating live, this wasn't one runaway process but an accumulation of long-lived background processes that never get cleaned up:
- A
--fork-session --resumeprocess (from the computer-use feature) had been running continuously for 10 days 2h46m, accumulating 499+ CPU-hours. It was still holding a full computer-use permission grant. Its own--resumetranscript file had already been deleted from disk, so the session was unresumable and purely dead weight — nothing referenced it anymore, yet it kept running. - Multiple MCP servers for the same integration were alive concurrently: 6 separate
sentry-mcpnode processes and 4 separateplaywright-mcpprocesses, some multiple days old. Each concurrent Claude Code session appears to cold-start its own copy of the same MCP server vianpxrather than sharing/pooling one — so N concurrent sessions of the same project cost N× the server processes for identical MCP config.
We maintain a local cleanup script to reclaim memory, but it made no difference here because neither process class falls into anything it checks for (wedged build-tool invocations, idle subprocess missions, headless browser orphans, dead test-runner chains) — forked/resumed sessions and MCP servers aren't reaped by anything, ours or (as far as we can tell) Claude Code's own process lifecycle.
What Should Happen?
Long-lived forked/resumed sessions that go idle — especially ones whose --resume transcript no longer exists on disk — shouldn't persist indefinitely holding permission grants and consuming CPU. Separately, MCP servers spawned per-session for the same project/config would ideally be poolable/shared across concurrent sessions of that project, rather than one full cold-start per session.
Error Messages/Logs
None — the processes just kept running silently, no error surfaced.
Steps to Reproduce
- Start a Claude Code session using the computer-use feature (
mcp__computer-use__*tools) via--fork-session --resume <transcript path>. - Let the session go idle without an explicit exit/close (e.g. close the terminal tab, or move on to other work, without ending the CLI session cleanly).
- Days later, check
ps aux | grep claude— the forked session process is still alive and still holding its granted permissions, even if its own--resumetranscript file has since been deleted/rotated. - Separately: open several concurrent Claude Code sessions against the same project with an
npx-based MCP server configured (e.g.sentry-mcp,playwright-mcp). Each session spawns its own server process instead of sharing one already running for that project.
Note: we don't have a minimal standalone repro outside our normal multi-session workflow — this was found via live ps/vm_stat inspection on an actively-used machine, not a constructed test case.
Claude Model
Not sure / Multiple models
Is this a regression?
Yes, this worked in a previous version
Last Working Version
Not pinpointed — reported as running smoothly prior to this recent stretch, but we don't have an exact last-known-good version to cite.
Claude Code Version
2.1.221 (Claude Code) — notably, 3 different versions (2.1.219, 2.1.220, 2.1.221) were found running concurrently as live processes on the same machine, suggesting version upgrades don't consolidate or replace processes from a prior version.
Platform
Anthropic API
Operating System
macOS
Terminal/Shell
Terminal.app (macOS)
Additional Information
- Machine snapshot at time of investigation: ~15GB/16GB physical memory in use, load average 30+ across all cores, ~70%+ CPU time in kernel/system space vs ~27% user space — consistent with memory-pressure thrashing rather than genuine compute load.
- The stale computer-use session above was killed live via a targeted
SIGTERMto confirm it was safe to reap: it took ~10 seconds to exit cleanly, noSIGKILLneeded. Average CPU utilization across its full lifetime worked out to ~2% (499 CPU-hours / ~243 wall-clock hours) — low but non-zero, so a naive "zero CPU" idle check wouldn't have caught it either. - Happy to share the full
ps/vm_statoutput from the investigation if useful.