Terminal renderer CPU spin: 100% CPU with 625K writes/0 blits on large session
Description
Claude Code enters a pathological state where the main thread consumes 100% CPU due to the terminal renderer performing ~625,000 write operations with zero blits (no diffing optimization) per render cycle. The session becomes unusable (30+ second input lag) and requires kill -9 to terminate.
Additionally, raw JSONL session/API data (including requestId, usage, cache_read_input_tokens, stop_reason, etc.) is rendered directly to the terminal instead of being parsed.
Environment
- Version: 2.1.22
- Platform: Linux 6.11.0-1016-nvidia (aarch64)
- Terminal size: 2099x472
- Runtime: Bun
Reproduction
- Start a session in a large Rust project with
rust-analyzerMCP server - Launch 50+ subagents (background Task agents) over ~1.5 hours
- Session progressively becomes unresponsive
- Raw JSONL appears in terminal output instead of rendered content
- CPU hits 100% and stays there permanently
kill(SIGTERM) does not work; requireskill -9- Resuming with
claude --continueimmediately reproduces the 100% CPU state
Diagnostic Data
Debug log (~/.claude/debug/<session-id>.txt)
The key line repeating every ~17 seconds:
High write ratio: blit=0, write=625433 (100.0% writes), screen=2099x472
Full tail of debug log:
2026-01-28T22:57:43.905Z [DEBUG] Stream started - received first chunk
2026-01-28T22:58:02.253Z [DEBUG] High write ratio: blit=0, write=625433 (100.0% writes), screen=2099x472
2026-01-28T22:58:19.847Z [DEBUG] High write ratio: blit=0, write=625433 (100.0% writes), screen=2099x472
2026-01-28T22:58:19.866Z [ERROR] AxiosError: Error
at <anonymous> (/$bunfs/root/claude:47:10681)
2026-01-28T22:58:19.880Z [ERROR] Error: 1P event logging: 10 events failed to export (code=ECONNABORTED, timeout of 10000ms exceeded)
2026-01-28T22:58:55.220Z [DEBUG] High write ratio: blit=0, write=625432 (100.0% writes), screen=2099x472
2026-01-28T22:59:12.825Z [DEBUG] High write ratio: blit=0, write=625676 (100.0% writes), screen=2103x472
Process diagnostics
PID %CPU %MEM VSZ RSS ELAPSED
1482399 79.0 3.0 94.3g 3.7g 01:11:19
- Main thread (PID = process PID) at 99.9% CPU; all other threads (Bun Pool, HTTP Client, File Watcher) at 0%
- Killing
rust-analyzerchild process had no effect on CPU - 50 threads total, only main thread spinning
- Session grew to 3.7GB RSS / 94GB VSZ
Raw JSONL in terminal output
Instead of rendered content, the terminal displayed raw API transport data:
{"stop_reason":null,"stop_sequence":null,"usage":{"input_tokens":1,
"cache_creation_input_tokens":307,"cache_read_input_tokens":148581,
...},"requestId":"req_011CXaW3Yr62aB1dFwmcgMME","type":"assistant",
"uuid":"97197d7e-...","timestamp":"2026-01-28T21:44:02.136Z"}
Including subagent permission errors rendered raw:
{"toolUseResult":"Error: Permission to use Write has been auto-denied
(prompts unavailable).","sourceToolAssistantUUID":"97197d7e-..."}
Analysis
The terminal renderer appears unable to diff/blit the screen buffer when the content exceeds a certain size, falling back to full rewrite of ~625K characters every render cycle. This creates a CPU-bound hot loop in the main Bun event loop that starves all other processing (input handling, API calls, etc.).
The raw JSONL rendering suggests the output parsing pipeline also breaks down, possibly related to the same buffer size issue.
Steps ruled out
rust-analyzerMCP server: killed it, no CPU change- Zombie child processes: already reaped, no effect
- Session history loading: RSS was dropping while CPU stayed at 100%, ruling out memory-bound loading
- Network issues: telemetry ECONNABORTED errors are secondary (caused by the main thread being too busy)
This issue has 13 comments on GitHub. Read the full discussion on GitHub ↗