High CPU when idle due to stdin EOF busy-loop after terminal is closed (/dev/pts/10)
Open 💬 3 comments Opened Feb 8, 2026 by hamza-u
💡 Likely answer: A maintainer (etraut-openai, contributor)
responded on this thread — see the highlighted reply below.
What version of Codex CLI is running?
codex-cli 0.98.0
What subscription do you have?
Team Plan
Which model were you using?
gpt-5.2-codex
What platform is your computer?
Linux 6.8.0-79-generic x86_64 x86_64
What terminal emulator and version are you using (if applicable)?
Xterm.js (PTY-backed terminal on the server side, exposed over WebSocket)
What issue are you seeing?
Codex can spin at ~100% CPU while idle if its stdin points to a deleted TTY.
It repeatedly calls read(0, ..., 1024) and gets EOF (= 0) in a tight loop with no backoff/exit.
What steps can reproduce the bug?
Repro steps (
- Start Codex in terminal A.
- Cause terminal A/PTY to disappear (close terminal/session, detached invalid
PTY, etc.).
- Leave Codex process running.
- Observe high CPU from one thread and repeated read(0)=0 via strace.
Impact
- Sustained high CPU while “idle”
- Wasted resources and battery
- Misleading “Codex is busy” state
What is the expected behavior?
- On persistent stdin EOF, Codex should either:
- Exit cleanly, or
- Sleep/backoff and avoid busy-spin CPU usage.
Additional information
_No response_
3 Comments
Hello team,
I wanted to follow up on this issue regarding high CPU usage when idle due to stdin EOF busy-loop after terminal closure, it’s been about 2 weeks with no response yet.
Could someone from the team or community provide an update on it?
Thanks in advance, happy to provide any additional details if needed.
@hamza-u, we're pretty far behind on bug reports at the moment. I'm triaging based on impact. You're the only one who as reported this issue so far so it's pretty far down the priority list. We'll get to it eventually — or sooner if other users also run into it.
Re the triage note above about being the only reporter — this now has a documented root cause and a partial upstream fix in flight, so it may be cheaper to close out than its priority suggests.
The loop is in crossterm's
UnixInternalEventSource::try_read: once the pty is gone the descriptor stays permanently read-ready whileread()returnsOk(0)(or fails withEIO), and neither case breaks the inner loop — onlyWouldBlockdoes, and it never comes. Upstream issue: crossterm#793, open since 2023. Fix in progress: crossterm#1067.Two caveats on that fix, from testing its branch: it stops the CPU spin, but for async
EventStreamconsumers (which is what the Codex TUI uses) the error still never reaches the consumer, so the process goes idle instead of exiting — details in my comment on the PR. And the crossterm fork that Codexmaincurrently pins,openai-oss-forks/crossterm@f69a4a0, does not contain the fix at all. #14962 has the Codex-side analysis; I have added the fork-gap verification and a deterministicpty.fork()reproduction there.Also seen since this was filed, by different reporters: #13928, #14962, #16862, #19958, #28315, #28794, and closed #21021. I hit it on macOS/Apple Silicon with the standalone 0.145.0 binary — two hot orphans consuming about one core each, one of which had been alive for 2d11h with 953 CPU minutes accumulated.