Where does the bug appear (feature/product)?
Cursor IDE
Describe the Bug
Extension-host processes orphaned after window close/reuse — SIGTERM ignored, requires SIGKILL (root cause analysis + workaround)
Environment
- Cursor 2.6.21
- macOS 15 (Darwin 24.6.0)
- Apple Silicon (M-series), 36 GB RAM
Bug Description
When a Cursor window is closed, and a different project reuses its slot, the old extension-host processes are never terminated. They enter a busy-wait loop at ~94% CPU per process and ignore SIGTERM — only SIGKILL works. Over hours/days, this accumulates and exhausts all system memory.
Root Cause Identified
Cursor assigns internal window slots (visible as [N-M] in process names via ps aux). When slot N is reused for a new project, new extension hosts [N-new] are spawned, but the old [N-old] hosts are never killed. The orphaned hosts enter a spin loop — likely waiting for IPC from a renderer that no longer exists.
Evidence
Machine with 3 Cursor windows open. ps aux shows 16 extension-host processes — 9 legitimate, 7 orphaned zombies:
| Process | CPU | Accumulated | Status |
|---|---|---|---|
extension-host (user) Project-A [2-7] |
93% | 789 min (13 hours!) | window closed hours ago — process leaked |
extension-host (user) Project-B [3-13] |
94% | 188 min | Window closed — leaked |
extension-host (user) empty [4-16] |
94% | 56 min | Slot 4 was reused by another project — old “empty” host orphaned |
extension-host (user) empty [5-22] |
93% | 40 min | Slot 5 reused — orphaned |
extension-host (user) Project-C [6-31] |
91% | 19 min | Window closed — leaked |
extension-host (user) Project-C [7-37] |
91% | 17 min | Window closed — leaked |
extension-host (user) empty [6-28] |
93% | 28 min | Slot 6 reused — orphaned |
| Total | 648% | 7 zombies, each pinning a CPU core |
The [N-M] slot numbers prove the pattern: slots 4, 5, and 6 each have two extension hosts — the old orphan and the new legitimate one.
System Impact
- 115 GB of memory committed on a 36 GB machine
- macOS compressor holding 71 GB compressed into 18 GB RAM (4:1 ratio)
- 31.5 GB swap used (out of 32 GB)
- Load average: 78 (machine has ~12 cores)
- System is nearly unusable
Key Finding: SIGTERM Is Ignored
kill 69042 # SIGTERM — process continues at 93% CPU
kill 69042 # again — no effect
kill -9 69042 # SIGKILL — process dies immediately
This confirms the extension host’s event loop or signal handler is stuck. Normal kill (SIGTERM) has zero effect.
After SIGKILL Cleanup
| Metric | Before | After (45 seconds) |
|---|---|---|
| Load average | 78 | 24 (dropping) |
| Free RAM | 0.07 GB | 5.4 GB |
| Swap | 31.5 GB | 11.0 GB |
| Compressor | 71 GB equivalent | 34 GB |
Workaround
launchd watchdog that kills zombie extension-host processes every 5 minutes:
#!/bin/bash
# ~/bin/cursor-watchdog.sh
# Kills extension-host processes above 80% CPU (normal hosts never exceed 5%)
ps aux | grep "[C]ursor Helper (Plugin)" | grep "extension-host" | \
awk '$3 > 80 {print $2}' | xargs kill -9 2>/dev/null
<!-- ~/Library/LaunchAgents/com.user.cursor-watchdog.plist -->
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN"
"http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>Label</key>
<string>com.user.cursor-watchdog</string>
<key>ProgramArguments</key>
<array>
<string>/bin/bash</string>
<string>/Users/YOU/bin/cursor-watchdog.sh</string>
</array>
<key>StartInterval</key>
<integer>300</integer>
<key>RunAtLoad</key>
<true/>
</dict>
</plist>
Install: chmod +x ~/bin/cursor-watchdog.sh && launchctl load ~/Library/LaunchAgents/com.user.cursor-watchdog.plist
Suggested Fix
When a Cursor window is disposed, the main process should:
- Send SIGTERM to associated extension-host processes
- Wait a grace period (e.g., 5 seconds)
- Send SIGKILL to any that haven’t exited
- Or better: use a process group (
setpgid) so closing the window kills the entire process tree
Related Issues
- VS Code #194477: Zombie extension hosts running at 100%
- Claude Code #14446: Extension host restarts cause orphaned processes
Steps to Reproduce
- Open 3+ different projects in Cursor as separate windows
- Close 2 of the windows (Cmd+W or File → Close Window)
- Open new projects in Cursor (reuses the closed window slots)
- Wait 5-10 minutes
- Run
ps aux | grep "extension-host" | awk '$3>50'in Terminal - Observe: old extension-host processes from closed windows are still running at ~94% CPU each
- Run
kill <pid>— process survives. Runkill -9 <pid>— process dies.
Expected Behavior
Extension-host processes should terminate when their window is closed. At minimum, if SIGTERM fails, Cursor should escalate to SIGKILL after a grace period.
Operating System
MacOS
Version Information
Cursor 2.6.21
Does this stop you from using Cursor
Yes - Cursor is unusable