Windows: claude.exe session processes accumulate and are never terminated, causing high RAM/disk usage over a work day
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.exeprocesses, all children of the main GUI process, each runningclaude.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
- Open Claude Desktop on Windows.
- 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.
- Watch
claude.exeprocess count via Task Manager orGet-Process -Name claudein 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.
Showing cached comments. Read the full discussion on GitHub ↗
4 Comments
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
Steps to reproduce
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:
Combined memory usage: ~30 GB from two idle, orphaned shells.
Impact
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:
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 Code2.1.280, 64 GB RAM.After ~14h with the app open (launched 09:31, measured 23:29):
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 asisRunning: 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.pwsh.exe+ 65conhost.exe(~2.4 GB) parented to the Desktop utility process that hosts the terminal panes, roughly one set per loaded session.git fsmonitor--daemon run --detachprocesses (~1.6 GB) with dead parents, because I hadcore.fsmonitor=trueglobally and agents touched many repos and worktrees. Same mechanism as #91763; besides RAM, it's the thing that blocks relaunch after auto-update.bashchain 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 byCLAUDE_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.
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.exesession processes = 7.7 GB commit, enough to exhaust system commit on a 32 GB box.Lifecycle
--resume) at app start, even when that session is never used during the run.Idle CLI floor ~400-470 MB private commit per process, flat over time (not a leak):
Terminal pane: the node-pty host utility process spawns a bare
powershell.exeper 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
--resumeon next interaction; spawn lazily for restored-but-untouched windows; reap terminal-pane shells for sessions not shown; lazily commit thread stacks.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 (behaviourunchanged 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 --servedaemon with no sessions under it | 17 days || Chromium profiles left in
/tmpby 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 writeshousekeeping 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 noconversation activity for up to 28 days.
server --servedaemons accumulate separately. Each client app updatespawns 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
MemoryHighlimit, the kernel did not kill anything — it reclaimed pages theprocesses 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"fromthe transcript body rather than trust
mtime, keep sessions with a runningchild 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.