VS Code extension leaks Claude processes when closing tabs/panels (WSL2)

Resolved 💬 2 comments Opened Feb 19, 2026 by flavio-bongiovanni Closed Feb 20, 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?

When using Claude Code through the VS Code extension on WSL2, closing a tab or panel in VS Code does not terminate the associated Claude Code process or its MCP server children. These processes accumulate over time, consuming significant memory.

After a typical day of work (opening/closing ~5 Claude panels), I found:

| Resource | Count | RAM |
|----------|-------|-----|
| Orphaned Claude Code instances | 5 | ~2.7 GB |
| Orphaned MCP servers (engram + beacon) | 10 | ~540 MB |
| Stopped terminal process (lost PTY) | 1 | ~957 MB |
| Total waste | 16 processes | ~4.3 GB |

This is ~28% of available RAM on a 16GB WSL2 system.

Root Cause Analysis

VS Code extension sessions (majority of leaks):

  • Each Claude panel spawns a Claude Code binary + MCP server children
  • When the VS Code panel is closed, the extension closes its socket end, but the Claude process stays alive in Sl+ state, blocked on stdin (which is a socket, not a terminal)
  • The processes are children of the VS Code Server node process (PID persists), so they're not reparented to init — they just sit there indefinitely
  • No inactivity timeout exists to self-terminate

Terminal sessions (secondary):

  • When a terminal emulator tab is closed without sending SIGHUP (common in tmux, some terminal emulators), the Claude process receives SIGTTOU when trying to write to the now-deleted PTY
  • It enters T (stopped) state and stays there forever, holding ~1GB RAM
  • File descriptors show: 0 -> /dev/pts/7 (deleted) — clear indicator

Process tree evidence

node (PID 1020, VS Code Server, running 2 days)
├── claude --output-format stream-json ... (PID 105787, 760MB, idle 12h)
│   ├── python -m claude_engram.mcp_server (50MB)
│   └── python -m claude_beacon.mcp_server (55MB)
├── claude --output-format stream-json ... (PID 185371, 483MB, idle 12h)
│   ├── python -m claude_engram.mcp_server
│   └── python -m claude_beacon.mcp_server
├── claude --output-format stream-json ... (PID 457694, 593MB)
│   └── ... (same pattern)
├── claude --output-format stream-json ... (PID 598042, 849MB)
│   └── ...
└── claude --claude-in-chrome-mcp (PID 640890, 260MB)

All had /proc/{pid}/stat last modified 12+ hours ago — completely inactive.

Suggested Fix

  1. Extension side: Send SIGTERM to the Claude child process when the associated panel/tab is disposed
  2. Claude Code side: Implement an inactivity timeout — if no stdin activity for N minutes (configurable, default 30?), self-terminate
  3. Claude Code side: Handle SIGHUP properly — when the controlling terminal is destroyed, exit gracefully instead of entering stopped state

Environment

  • OS: Ubuntu 22.04 on WSL2 (Linux 6.6.87.2-microsoft-standard-WSL2)
  • VS Code: 1.109.4
  • Claude Code extension: 2.1.44 (linux-x64)
  • Claude Code CLI: 2.1.37
  • Shell: bash
  • RAM: 16GB (WSL2 limit)

Workaround

I wrote a cleanup script that detects orphaned Claude processes by checking for stopped state, deleted terminals, and dead parent connections. Running it via cron every 2 hours:

# ~/.local/bin/claude-cleanup --force (in crontab)
# Detects orphans by: T state, deleted PTY, dead parent
# Kills MCP children first, then Claude process
# Never kills engram daemon or current interactive session

Related Issues

  • #24564 — Shell snapshot subprocess leaks (similar family, different mechanism)
  • #16487 — Background task process tree cleanup on timeout
  • #25023 — Memory leak reports (may be partially caused by this)

View original on GitHub ↗

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