[Bug] High CPU usage (50-126%) in idle state - main thread busy-wait
Bug Report
Claude Code Version
2.1.29 (installed via brew on macOS)
Description
The Claude Code main process consumes 50-126% CPU continuously even when idle. The main thread is in state R (Running) instead of S (Sleeping), indicating a busy-wait loop in the core event loop.
System Info
- macOS 26.2 Tahoe (Darwin 25.2.0)
- MacBookPro16,1 (Intel Core i9-9880H, 16GB RAM)
- Shell: zsh 5.9
Evidence
Process state:
PID COMMAND %CPU TIME STAT
83726 claude 50.7 30:38 R ← Main thread RUNNING instead of SLEEPING
Thread breakdown:
- Main thread: STAT=R, 50.7% CPU, 25min CPU time
- Other threads: STAT=S, 0-2% CPU, sleeping normally
Subprocess comparison:
83726 claude 31:00.99 ← The problem
83734 npm exec mcp-server 0:02.14 ← Normal
83735 npm exec chrome... 0:02.06 ← Normal
83744 pyright-langserver 1:02.02 ← Normal
83745 clangd 0:00.08 ← Normal
MCP servers and LSPs consume minimal CPU. The issue is in Claude Code's main event loop.
Impact
- Reduced battery life on laptops
- Fan noise
- System slowdown during long idle sessions
- 30+ minutes of CPU time accumulated in ~1 hour
Expected Behavior
When idle, the main thread should be in state S (Sleeping) with near 0% CPU, waiting for events via kqueue/epoll instead of busy-waiting.
Steps to Reproduce
- Start Claude Code:
claude - Let it idle (no commands, no active operations)
- Run:
top -o cpuorps -p <claude_pid> -o pid,stat,%cpu,time - Observe main thread at 50-126% CPU with STAT=R
Diagnosis
The main event loop appears to be using busy-wait polling instead of proper event notification. This is a classic performance bug where the loop doesn't block/sleep when no events are pending.
Suggested Fix
Ensure the main event loop blocks on kqueue/selector when idle, only waking when there's actual work to do (input, IPC events, timer events, etc.).
This issue has 2 comments on GitHub. Read the full discussion on GitHub ↗