[Bug] Idle session busy-spins CPU with sched_yield in worker threads instead of blocking

Open 💬 0 comments Opened Jul 11, 2026 by perler

Bug Description
Idle Claude Code session busy-spins CPU instead of sleeping. When a session is idle at the prompt (last turn stop_reason=end_turn, waiting for input), it burns ~3-9% of a CPU core continuously and never quiesces. It happens whether or not a terminal is attached, so it's not an attached-TUI redraw artifact.

strace on an idle session (2s sample, ~4% CPU, ~27 threads) is dominated by sched_yield + futex, not epoll:

50.03% futex 381 calls (67 errors) 24.47% restart_syscall 12 calls 22.16% sched_yield 604 calls 2.34% epoll_pwait2 8 calls

sched_yield firing 600+ times in 2s on an idle process = a busy-yield spin. The main thread is correctly parked in epoll_pwait2; the ~27 worker/render threads spin. Thread count is stable (not a leak).

Impact: fine for one session, but we keep many sessions persistent (so they can be resumed from different editor instances). ~30 idle sessions synchronized their spin and drove a 16-core host to load average 114 until we killed the idle ones.

Env: Claude Code 2.1.207, Node v22.22.0, Ubuntu 24.04 (kernel 6.8), 16 cores. Sessions run headless under dtach (claude --dangerously-skip-permissions --session-id ); reproduces with an attached terminal too.

Repro: start a session, let it go idle at the prompt, leave it, then strace -f -c -p <pid> for 2s -> dominated by futex+sched_yield, not epoll. CPU sits at a few percent, not 0%.

Expected: an idle session should be parked (blocked in epoll/read) at ~0% CPU until input/event arrives.

Likely area: a render/animation loop or worker-thread condition-wait that falls back to sched_yield and doesn't quiesce when there's nothing to render and no input pending (Ink loop / interval timer / thread-pool wait). Main thread is fine; the worker threads are the ones spinning.

Environment Info

  • Platform: linux
  • Terminal: vscode
  • Version: 2.1.207
  • Feedback ID: 8c8c04e0-e808-4bcb-88c8-7f551eae0348

Errors

[]

View original on GitHub ↗