[BUG] High sustained CPU usage (~100% per instance) even when idle
Preflight Checklist
- [x] I have searched existing issues and this hasn't been reported yet
- [x] This is a single bug report (please file separate reports for different bugs)
- [x] I am using the latest version of Claude Code
What's Wrong?
Description
Two instances of Claude Code CLI running simultaneously each consume ~100% CPU sustained, even between interactions when both should be idle. On a 4-core machine this makes the system noticeably sluggish.
Environment
- Claude Code version: 2.1.29
- Node.js: v22.19.0
- OS: Linux Mint 21.3 (kernel 5.15.0-164-generic)
- Hardware: 4 CPU cores, 7.5 GB RAM
- Terminal: Guake (but issue is in the claude process itself)
Observed behavior
Both claude processes pin at ~100% CPU each continuously, even when no tool calls are running and no output is being streamed:
PID USER %CPU %MEM RES COMMAND
3225 jan 102% 9.6% 756 MB claude
5342 jan 89% 8.4% 660 MB claude
A second measurement 2 minutes later with both sessions idle between interactions:
PID USER %CPU %MEM RES COMMAND
3225 jan 101% 9.9% 781 MB claude
5342 jan 97% 9.0% 705 MB claude
Each process has ~13-14 threads. Virtual memory mapped is ~71 GB per process (normal for V8 but noted for completeness).
---
What Should Happen?
Expected behavior
Between interactions, CPU usage should drop to near zero since the CLI is mostly waiting for user input or network responses.
Error Messages/Logs
Steps to Reproduce
- Open two terminal tabs
- Run claude in each
- Have a conversation in one; leave the other idle
- Observe CPU usage with top
Claude Model
Opus
Is this a regression?
Yes, this worked in a previous version
Last Working Version
_No response_
Claude Code Version
2.1.29
Platform
Anthropic API
Operating System
Ubuntu/Debian Linux
Terminal/Shell
Other
Additional Information
- No MCP servers configured
- The high CPU is in the claude Node.js process itself, not in any child/tool processes
- Single instance also shows ~100% CPU, it's not contention between the two
Showing cached comments. Read the full discussion on GitHub ↗
13 Comments
Found 3 possible duplicate issues:
This issue will be automatically closed as a duplicate in 3 days.
🤖 Generated with Claude Code
Confirming on same setup - v2.1.29, Linux Mint (kernel 6.14.0-37-generic)
Thread-level breakdown shows the cause clearly:
This matches the root cause identified in #18280 - the 60Hz timer causing constant allocation/deallocation, with GC (HeapHelper threads) running continuously to clean up.
Additional observation: Restarting Claude Code and resuming the conversation (
/resume) temporarily improves CPU usage, but it creeps back up during the session. This suggests the memory pressure accumulates over time rather than being constant from startup.a hot path like this should not have any allocations............ this is very concerning..... how is GC in the frame path be passing review, that's crazy
npm install -g claudefix
You're welcome
@jonhardwick-spec
⚠️ Warning about
claudefixpackageI analyzed this package before installing and found several concerns:
It won't fix the high CPU issue:
Adware-like behavior:
claudebinary with a wrapperIf you just want memory limits, you can do it yourself without third-party wrappers:
The actual fix needs to come from Anthropic — it's a known bug in Claude Code's Ink/React TUI rendering causing memory thrashing and busy-wait loops. See issues #18280, #22275, #10493.
I'd recommend waiting for an official fix rather than installing packages that replace your binaries and add promotional content.
What version does not suffer from this issue? its pretty useless as is after a short time my machine comes responsive with 2-3 sessions running in parallel my VM dies of context switching - and the TUI is so slow that i barely can add texts in it..
I downgraded to 2.1.25 and I haven't seen this problem since.
Additional diagnostic evidence from debug logs - v2.1.31 on macOS
I'm seeing the same ~ 20% sustained CPU usage when idle on v2.1.31. Found relevant evidence
in the debug logs (~ /.claude/debug/*.txt) that may help pinpoint the issue:
This pattern repeats continuously every ~600ms even when completely idle (no user input, no
API calls, just waiting).
What this shows:
Environment:
nanobanana)
This correlates with the 60Hz timer theory - the renderer appears to be redrawing the entire
screen buffer on each tick rather than diffing and only updating changed regions.
perf stat data point: 48% of idle CPU is pure kernel/syscall overhead (v2.1.63, Fedora 43, kernel 6.18)
Adding a dimension I haven't seen in the other comments — the user/kernel cycle split:
Nearly half the idle CPU burn is kernel-side, driven by the syscall volume (~18K/sec). The userspace IPC of 2.03 means the JS itself runs efficiently when it does run — the waste is in how often it runs and the resulting syscall storm:
Bun upstream fix worth picking up
oven-sh/bun#27490 — bmalloc's
SYSCALLmacro retriesmadvise(MADV_DONTDUMP)with zero backoff onEAGAIN, causing HeapHelper threads to spin. Fixed upstream in oven-sh/WebKit but may not be in the Bun version bundled with Claude Code. This would directly reduce thesched_yield+madvisepressure.@claude I don't think that my comment is relevant for https://github.com/anthropics/claude-code/issues/31812 see https://github.com/anthropics/claude-code/issues/22275#issuecomment-3984332297
@claude @diamondsea's
High write ratio: blit=1034, write=62508 (98.4% writes)finding above lines up with measurements I have on the WSL2 side. Posting them here because they show where the writes go and why the relays burn CPU on the Windows side.Setup
Linux side: per-claude pty I/O over a 10-second sample (
/proc/{pid}/io)Every idle session writes the same
8 bytes/secto its pty, about 1 write syscall/sec. Some sessions also receive~50 bytes/secback, about 2 read syscalls/sec. Other identical idle sessions get nothing back.Windows side:
wsl.exerelay CPU and thread countAffected relays grow from the normal 4 threads to 7-12 as they spin to keep up with the bidirectional traffic. Task Manager's Processes view rolls up child-process CPU under the parent, so the visible figure attributed to "Windows Terminal" reaches 30-43% of one core with 2-3 affected sessions.
WindowsTerminal.exeitself uses ~0% during the same sample. The CPU budget is being consumed entirely by itswsl.exerelay children.Why this matters for this issue
All idle sessions emit identical
8 bytes/sec. The differentiator is whether the terminal-side loops the data back. Once a relay enters the looping state it stays there for that relay's lifetime, and claude has no choice but to respond to whatever VT queries arrive (DSR cursor position, focus events, mouse motion). The user-visible CPU consequence is sustained 5-25% per affected relay on the Windows side with matching read throughput on the Linux side. That's the symptom this issue tracks.The chain: claude writes to pty, pty forwards to ConPTY relay, relay responds with what looks like cursor position reports or focus events, that response triggers the next claude write. The 16ms Ink re-render documented in #19393 likely explains why claude generates periodic outbound queries at idle to begin with.
Reproduction (~10 seconds, no install)
Linux side, from any shell with multiple
claudePIDs:Windows side, in PowerShell:
The looping
wsl.exePIDs on the Windows side correspond to the claude PIDs reading non-zero bytes/sec on the Linux side. The mapping is exact in my testing.Workaround
Launching claude inside
tmuxeliminates the loop. tmux's pty layer absorbs the cursor-position / focus / mouse responses before they reach the Windows ConPTY relay, breaking the feedback path at the right layer. Same workaround validated in microsoft/terminal#17787 discussions.Related
Same family as several open and closed reports. Adding the WSL2/relay-side measurement may help connect them.
In this repo:
Cross-repo, Windows Terminal maintainers have closed similar reports as upstream/Ink:
ink-virtual-listor moving off Ink.process.stdin.setRawMode(true)overwriting flags. Filed upstream as oven-sh/bun#25663 and nodejs/node#61161.Outstanding
I haven't captured the exact 8-byte sequence being emitted. That's the next investigation step if there's interest in narrowing the initiating side.
That's a rather unfortunate mid-sentence abbreviation of my comment. FWIW I'm happy to assist with Claude's perf issues wherever I can.
@lhecker No idea what you're talking about. Feel free to post the missing context if I somehow misrepresented your comment.