Windows: statusline pwsh.exe processes never exit -- hundreds of orphans per hour under multi-session use
Summary
On Windows, every statusline refresh spawns a pwsh.exe process that never exits. Under normal multi-session use the host accumulates hundreds of orphaned pwsh.exe processes per hour, degrading the machine until they are manually killed.
Environment
- Claude Code v2.1.231 (also observed on earlier 2.1.x)
- Windows 11, PowerShell 7 installed at
C:\Program Files\PowerShell\7\pwsh.exe - Custom statusline configured as a PowerShell script (
~/.claude/statusline/statusline.ps1) - Multiple concurrent Claude Code sessions (interactive and
claude -p), auto mode on
Observed behavior
Each statusline invocation appears as:
"C:\Program Files\PowerShell\7\pwsh.exe" -NoProfile -ExecutionPolicy Bypass -File C:/Users/<user>/.claude/statusline/statusline.ps1
The script itself completes (its output renders in the statusline), but the spawned pwsh.exe host process remains alive indefinitely. The processes are idle (no CPU accumulation) but occupy the process table and memory.
Measured accumulation across one working day (2026-08-13), counted with a WMI filter on the command line and swept with Stop-Process between measurements:
| local time | orphaned statusline pwsh.exe count | note |
|---|---|---|
| ~13:50 | 33 | swept to 0 |
| ~14:05 | growth restarts | oldest surviving process timestamped 14:04:58 |
| ~17:30 | 636 | swept to 0 |
| 19:51 | 1010 | oldest 14:04:58, newest 19:51:27; swept 1007 |
That is roughly 175 new orphaned processes per hour sustained, scaling with the number of concurrent sessions (earlier observations: ~19/minute at peak with 4 sessions active; >2200 accumulated over a multi-day uptime before this was identified).
Impact
Beyond memory/process-table growth, the leak has measurable downstream cost: any tooling that enumerates processes slows dramatically. On this host, test-suite legs that perform a process census went from seconds to 16-22 minutes at 600+ orphans, and a CI-verification workflow wedged twice on the same day as a result.
Workaround
Periodic manual sweep:
$cut=(Get-Date).AddMinutes(-5)
Get-CimInstance Win32_Process -Filter "Name='pwsh.exe'" |
Where-Object { $_.CommandLine -like '*statusline*' -and $_.CreationDate -lt $cut } |
ForEach-Object { Stop-Process -Id $_.ProcessId -Force -ErrorAction SilentlyContinue }
Expected behavior
The statusline host process should exit after producing its output (or be reaped by the spawning session), keeping the steady-state count at or near the number of live sessions.