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 (

  1. Start Codex in terminal A.
  2. Cause terminal A/PTY to disappear (close terminal/session, detached invalid

PTY, etc.).

  1. Leave Codex process running.
  2. 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:
  1. Exit cleanly, or
  2. Sleep/backoff and avoid busy-spin CPU usage.

Additional information

_No response_

View original on GitHub ↗

3 Comments

hamza-u · 6 months ago

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.

etraut-openai contributor · 6 months ago

@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.

roazanas · 28 days ago

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 while read() returns Ok(0) (or fails with EIO), and neither case breaks the inner loop — only WouldBlock does, 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 EventStream consumers (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 Codex main currently 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 deterministic pty.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.