Windows: claude.exe session processes accumulate and are never terminated, causing high RAM/disk usage over a work day

Status Open
Reported on v2.1.275
Maintainer reply None cached
Activity 9 comments · opened Sep 23, 2026

Summary

On Windows, claude.exe background processes backing Claude Code sessions/tabs in the Claude Desktop app are not terminated when a session finishes or is closed. They keep accumulating in the background for the entire time the app stays open, consuming RAM and disk space, even though the app's own session list correctly shows those sessions as not-running.

Environment

  • OS: Windows 11 Home 10.0.26200
  • Claude Desktop: Windows Store package Claude_2.2553.1.0_x64
  • Claude Code CLI: 2.1.275 (bundled under %APPDATA%\Claude\claude-code\)
  • Machine RAM: 7.8 GB total (low-RAM machine, makes the impact worse)

What I observed

After roughly 11 hours of normal use (opening many Code tabs/tasks across a work day, most of which had long since finished), Task Manager and Get-Process -Name claude showed 42 claude.exe processes consuming ~3.4 GB of RAM, while Get-CimInstance Win32_Process -Filter "Name='claude.exe'" showed:

  • 1 main GUI process (the app window)
  • ~13 normal Electron helper processes (gpu-process, renderer, utility, crashpad-handler) — expected overhead for a single window
  • 27 additional top-level claude.exe processes, all children of the main GUI process, each running claude.exe --output-format stream-json --verbose --input-format stream-json ..., with creation timestamps spread from app launch until the time of inspection.

Cross-checking against the app's own session list: only 2 of ~48 sessions were actually marked isRunning: true. The other ~46 were already idle/finished (several with merged PRs from hours earlier), yet their backing claude.exe CLI process was still alive and resident.

Secondary effects on a low-RAM machine:

  • System RAM was at 98.7% used (0.1 GB free out of 7.8 GB), causing heavy paging.
  • Windows' system-managed pagefile grew to 21.5 GB reserved on disk to compensate.
  • Each session also leaves a scratch directory under %LOCALAPPDATA%\Temp\claude\<session-id>\ that is never cleaned up; these had accumulated to ~3 GB.

Steps to reproduce

  1. Open Claude Desktop on Windows.
  2. Over the course of several hours, open and complete many separate Code tabs/tasks/sessions (background agents, one-off questions, etc.), letting each finish naturally rather than force-closing the app between them.
  3. Watch claude.exe process count via Task Manager or Get-Process -Name claude in PowerShell.

Expected behavior

Once a Code tab/session is idle/finished (as reflected by isRunning: false in the session list), its backing claude.exe CLI process should be terminated (or pooled/reused), not left running indefinitely.

Actual behavior

The backing process for every session opened since app launch stays alive for as long as the app itself stays open, regardless of whether the session is finished. Process count only grows, never shrinks, until the entire app is force-quit.

Workaround found

Force-killing all claude.exe processes and relaunching the app resolves it temporarily — process count drops back to a normal baseline (~13, almost entirely standard Electron sub-processes for a single window) immediately after a clean relaunch, confirming the excess processes are not required for the app's normal operation.

Suggested fix

When a session/tab is closed or its task completes and it is not actively being used (not visible, not running a background agent, no pending remote-control connection), terminate its backing CLI process rather than keeping it resident for the lifetime of the app.

View original on GitHub ↗

4 Comments

davidatanetspain-blip · 21 days ago

Bug: Orphaned PowerShell processes leak memory after closing Claude Desktop (Windows)

Description

After closing Claude Desktop on Windows, the PowerShell sandbox processes it spawns for Claude Code sessions remain running as orphaned processes. These processes accumulate memory over time due to .NET garbage collection issues in PowerShell 5.1, reaching extreme levels (10-17 GB each) with no parent to terminate them.

Environment

  • OS: Windows 11 Home 10.0.26200
  • Claude Desktop version: 2.7032.0
  • Claude Code version: 2.1.280
  • Shell: Windows PowerShell 5.1 (powershell.exe)

Steps to reproduce

  1. Open Claude Desktop and use Claude Code for an extended session (multiple tool calls, file reads, greps, etc.)
  2. Close Claude Desktop
  3. Open Task Manager → sort by Memory

Expected behavior

All child PowerShell processes spawned by Claude Desktop should be terminated when the app closes.

Actual behavior

PowerShell processes remain running after Claude Desktop is closed. They accumulate memory indefinitely.

Evidence from this session

Two orphaned processes found after closing Claude Desktop:

| PID | Memory | Created | Parent PID |
|-----|--------|---------|------------|
| 12272 | 17.02 GB | 22:40:38 | 16916 |
| 35524 | 13.18 GB | 22:49:03 | 15132 |

Both had the same command line signature:

"C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe"
  -NoProfile -NonInteractive -ExecutionPolicy Bypass
  -Command "$__claudeCodeScript = $env:CLAUDE_CODE_SHELL_LAUNCHER_SCRIPT;
  $env:CLAUDE_CODE_SHELL_LAUNCHER_SCRIPT = $null;
  Invoke-Expression -Command $__claudeCodeScript"

Combined memory usage: ~30 GB from two idle, orphaned shells.

Impact

  • Severe memory pressure on the host system (30 GB consumed by zombie processes)
  • Requires manual intervention (Task Manager kill) to reclaim memory
  • Users may not notice until system performance degrades significantly

Suggested fix

Register a cleanup/shutdown hook in Claude Desktop that terminates all child PowerShell processes on app close. Other similar tools (e.g., Cowork) handle this correctly — their shell processes are properly cleaned up on exit.

Workaround

Manually kill high-memory PowerShell processes:

Get-Process powershell | Where-Object { $_.WorkingSet64 -gt 1GB } | Stop-Process -Force
lucasbp · 20 days ago

Same on my machine, with numbers from one work day.

Environment: Windows 11 Pro 10.0.26200, Claude Desktop 2.7032.0.0 (MSIX), bundled Claude Code 2.1.280, 64 GB RAM.

After ~14h with the app open (launched 09:31, measured 23:29):

  • 12 claude.exe --output-format stream-json ... session processes still resident, ~5.7 GB total (260 to 860 MB each). The app's own session list showed all of them as isRunning: false. Archiving the finished sessions did not free anything: the resident processes belonged to sessions opened that same day, and they only go away when the app restarts.
  • 16 pwsh.exe + 65 conhost.exe (~2.4 GB) parented to the Desktop utility process that hosts the terminal panes, roughly one set per loaded session.
  • 116 detached git fsmonitor--daemon run --detach processes (~1.6 GB) with dead parents, because I had core.fsmonitor=true globally and agents touched many repos and worktrees. Same mechanism as #91763; besides RAM, it's the thing that blocks relaunch after auto-update.
  • An orphaned bash chain from a Bash tool call hours earlier, parent dead (#62659, closed by the bot, not fixed).

Scheduled tasks make it worse: every run opens a new session, so recurring routines pile up loaded sessions all day.

Workaround I'm using until this is fixed: unset global core.fsmonitor, plus a scheduled PowerShell job every 2h that kills fsmonitor daemons and only reaps orphaned Claude Code shells (matched by CLAUDE_CODE_SHELL_LAUNCHER_SCRIPT / .claude/shell-snapshots, with PID-reuse checks). For the resident session processes, the only fix I have is restarting the app.

A per-session job with kill-on-close that also covers the Bash tool children, plus unloading idle session processes after some timeout, would cover all of the above.

cezkid · 16 days ago

Same on Windows 11 Pro 26200, Claude Desktop 2.9939.2.0 (MSIX), bundled CLI 2.1.281, 32 GB RAM. Adding what the earlier comment didn't have:

Snapshot: 28 claude.exe session processes = 7.7 GB commit, enough to exhaust system commit on a 32 GB box.

Lifecycle

  • One CLI process per session touched since app launch, kept until archive or app quit. No idle eviction.
  • Restored windows respawn their CLI eagerly (--resume) at app start, even when that session is never used during the run.
  • On this build, archiving does exit the CLI: archiving 4 finished sessions freed ~5 GB commit (1.6 -> 6.6 GB free, partly other workload settling in the same window).

Idle CLI floor ~400-470 MB private commit per process, flat over time (not a leak):

  • JS heap arena: ~1 GB reserved / 300-370 MB committed
  • Thread stacks: 30-32 threads, 18 MB reserved and 2-8 MB committed each => ~90 MB eagerly committed
  • JIT / gigacage: ~35 MB
  • Session transcripts are 0.5-1.4 MB on disk => footprint is not transcript data

Terminal pane: the node-pty host utility process spawns a bare powershell.exe per session viewed with the pane open; never reaped. 14 idle x ~63 MB.

Mitigation: Archive inactive sessions (Settings) helps, but granularity is days while accumulation happens within one working day, and running/background sessions are exempt.

Would fix it: exit the CLI of a session idle for N minutes and respawn with --resume on next interaction; spawn lazily for restored-but-untouched windows; reap terminal-pane shells for sessions not shown; lazily commit thread stacks.

kralikr · 16 days ago

Same behaviour on Linux with the desktop app connected to a remote shared
server
over SSH, which adds a dimension this report does not cover: the
machine is never restarted and the cost is multiplied by the number of people
using it.

Setup: Debian 13, 8 cores, 31 GB RAM, 5 developers, each with their own
system account and their own ~/.claude. Claude Code 2.1.284 (behaviour
unchanged since 2.1.221).

Measured over 11 days:

| | |
|---|---|
| session processes accumulated by one developer in a day | 41 (~10 GB RSS, ~260 MB each) |
| peak concurrent sessions across 5 developers | 55 |
| longest-running process with zero conversation activity | 28 days |
| orphaned server --serve daemon with no sessions under it | 17 days |
| Chromium profiles left in /tmp by browser automation | 299 dirs, ~8 GB |

Two details that may help pin it down:

Idle time cannot be read from the transcript's mtime. The app writes
housekeeping records (artifact watch, title, last prompt) that refresh the file
timestamp without any work happening in the session. Measured from the last
real "timestamp" entry in the transcript body, processes were running with no
conversation activity for up to 28 days.

server --serve daemons accumulate separately. Each client app update
spawns one with a new hash and the previous one keeps running. One user had
three at once, the oldest with no sessions under it at all.

Why a shared server makes it worse than a memory count suggests. Session
binaries are 250–340 MB and mapped into memory. When the user slice hit a cgroup
MemoryHigh limit, the kernel did not kill anything — it reclaimed pages the
processes immediately faulted back in. That turned into ~1 GB/s of sustained
disk reads while 24 GB of RAM sat free, saturated the datastore and took down
the VMware host the VM was running on. The limit was our own misconfiguration,
but the trigger was the accumulated session processes.

Workaround we run, in case it is useful to anyone else: a cron job that ends
sessions whose transcript shows no real activity for over 30 minutes, plus
daemons with no sessions under them. It has to read the last "timestamp" from
the transcript body rather than trust mtime, keep sessions with a running
child process, and terminate the whole process tree — signalling only the
session leaves its shells running under init. Over 11 days it ended 413
sessions and 67 daemons with no incidents.

Happy to provide more measurements from the shared-server setup if it helps.

Showing cached comments. Read the full discussion on GitHub ↗