Skip to content

High CPU usage (27-33%) when idle - busy-wait loop in sched_yield/futex #17142

Closed as not planned

Description

@nazmulidris

Summary

Claude Code consumes 27-33% of a CPU core when idle (waiting for user input), caused by a busy-wait loop pattern visible in syscall traces.

Environment

  • OS: Fedora 43 (Linux 6.18.3)
  • CPU: Intel Core i7-14700 (20 cores)
  • Claude Code version: Latest (installed via ~/.local/bin/claude)

Observed Behavior

Multiple Claude Code instances running:

PID CPU % Status
71457, 72589, 89061, 89978 0.3-0.4% Truly idle (from previous day)
614750 33.2% "Active" but waiting for input
946540 27.8% "Active" but waiting for input

The "active" instances are just sitting at a prompt, not processing anything.

Syscall Analysis

5-second strace on the 33% CPU process:

% time     seconds  usecs/call     calls    errors syscall
------ ----------- ----------- --------- --------- ----------------
 49.68    0.046981           7      5980           sched_yield
 33.58    0.031758           1     21884       165 futex
  6.08    0.005754        1150         5           wait4
  5.46    0.005159           3      1293           epoll_pwait2
  1.52    0.001439           0      5222           clock_gettime
  1.48    0.001402           0      2450           statx
  0.73    0.000687           0      1078           madvise
  ...
------ ----------- ----------- --------- --------- ----------------
100.00    0.094562           2     41221      1134 total

41,221 syscalls in 5 seconds (~8,200/sec) for an idle process.

Analysis

The syscall pattern indicates:

  1. sched_yield spam (5,980 calls) - Classic busy-wait: yielding CPU but immediately rescheduling
  2. futex contention (21,884 calls) - Heavy thread lock contention
  3. clock_gettime (5,222 calls) - Constant time polling
  4. statx (2,450 calls) - Frequent file stat checks (file watcher?)

This is busy-polling behavior - the process yields to be "nice" but immediately wakes up again instead of properly blocking on I/O.

Expected Behavior

Idle CPU usage should be <1% (similar to the 0.3-0.4% seen in truly idle instances from the previous day).

Impact

  • Battery drain on laptops
  • Unnecessary heat/power consumption on desktops
  • Wasted CPU cycles that could be used for compilation or other tasks

Reproduction

  1. Start claude in a terminal
  2. Let it sit idle at the prompt
  3. Observe CPU usage in top/htop or KDE System Monitor
  4. Run strace -p <pid> -c for 5 seconds to see syscall pattern

Activity

  1. github-actions commented on Jan 9, 2026

    @github-actions

    Found 3 possible duplicate issues:

    1. [BUG] Critical performance regression on WSL2: Slash commands trigger infinite futex spinlock causing 110% CPU usage (v2.0.76 & v2.0.67) #15689
    2. [BUG] 100% CPU due to busy-polling bug #11473
    3. [BUG] Excessive config file polling during UI render causes full CPU usage when arrow key is pressed to recall previous prompt #14054

    This issue will be automatically closed as a duplicate in 3 days.

    • If your issue is a duplicate, please close it and 👍 the existing issue instead
    • To prevent auto-closure, add a comment or 👎 this comment

    🤖 Generated with Claude Code

  2. ElliotCallender commented on Jan 23, 2026

    @ElliotCallender

    Hi! Claude and I wrote a patch for this until Anthropic fixes the root issue.

  3. cruppertautomation-ai commented on Jan 31, 2026

    @cruppertautomation-ai

    Additional Data Point: Native Linux, Different Pattern, Root Cause Identified

    Environment

    • Claude Code Version: 2.1.27
    • OS: Ubuntu 24.04.3 LTS (noble)
    • Kernel: 6.14.0-37-generic (PREEMPT_DYNAMIC)
    • Platform: Native Linux (NOT WSL)

    Key Finding: This is a Different Variant

    Your issue reports ~8,200 syscalls/sec from futex/sched_yield busy-wait. I'm seeing a different pattern:

    Metric Issue #17142 My Instance
    Syscalls/sec 8,200 400
    Root cause futex spinlock timerfd not relaxing
    Platform Fedora Ubuntu

    CPU is burned in userspace, not syscall overhead.

    Root Cause Identified: timerfd Firing Rate

    Direct measurement via strace -e read -c over 3 seconds on two instances:

    Instance Timer reads/3sec Reads/sec CPU% Status
    Stuck 89 ~30/sec 15% Bug active
    Recovered 3 1/sec 3% Properly idle

    30x difference in timer activity.

    The internal timerfd (fd 7) controls the event loop poll interval:

    • Stuck instance: epoll_pwait2 timeout = 1-16ms (60fps animation speed)
    • Recovered instance: epoll_pwait2 timeout = 100ms (proper idle)

    Hypothesis

    Claude Code sets a timerfd at ~30-60Hz for UI refresh (spinner, cursor, animation). When the session becomes idle, this timer should relax to 1Hz or stop. But sometimes it doesn't.

    This explains:

    • ✅ High CPU when "idle" = timer firing constantly
    • ✅ Intermittent = sometimes relaxes, sometimes stuck
    • ✅ strace can "fix" it = ptrace attach interrupts event loop, allows timer recalculation

    Schrödinger's Bug

    Notably, attaching strace to debug the issue caused one stuck instance to recover (timer relaxed from 30Hz to 1Hz). The act of observation changed the behavior.

    Recommendation

    Check for timers/intervals set for UI animations that don't get cleared or slowed when idle. The poll interval should relax to 100ms+ when truly idle.

  4. igor-nav commented on Feb 3, 2026

    @igor-nav

    v2.1.29 on WSL2/Linux 6.6.87. Fresh session, no tools running, 47% CPU at idle. 12% battery drain in 5 minutes on a laptop. This makes Claude Code nearly unusable for untethered work.

  5. ksacry-ft commented on Feb 3, 2026

    @ksacry-ft

    Here is an strace from my system:

    strace.txt

  6. github-actions commented on Mar 5, 2026

    @github-actions

    Closing for now — inactive for too long. Please open a new issue if this is still relevant.

  7. github-actions commented on Mar 12, 2026

    @github-actions

    This issue has been automatically locked since it was closed and has not had any activity for 7 days. If you're experiencing a similar issue, please file a new issue and reference this one if it's relevant.

  8. locked as resolved and limited conversation to collaborators on Mar 12, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    area:corebugSomething isn't workinghas reproHas detailed reproduction stepsperf:memoryplatform:linuxIssue specifically occurs on LinuxstaleIssue is inactive

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions