Codex native binary persists after session exit and consumes ~100% CPU per process (Rosetta/Apple Silicon) Labels: bug, performance

Open 💬 1 comment Opened Mar 8, 2026 by tomitayus

What version of Codex CLI is running?

v0.111.0

What subscription do you have?

puls

Which model were you using?

gpt-5.3-codex

What platform is your computer?

_No response_

What terminal emulator and version are you using (if applicable)?

_No response_

What issue are you seeing?

Description

After exiting interactive Codex sessions (via Ctrl+C), the native codex binary processes remain running in the background and spin
at
~98-99% CPU indefinitely. Multiple zombie-like processes accumulate over time, consuming significant system resources.

Environment

  • codex-cli version: 0.111.0
  • OS: macOS 26.4 (25E5223i) — Tahoe beta
  • Architecture: Apple M3 (arm64) — binary runs via Rosetta 2 (x86_64 translated)
  • Binary path: /usr/local/lib/node_modules/@openai/codex/node_modules/@openai/codex-darwin-x64/vendor/x86_64-apple-darwin/codex/

codex

  • Shell: zsh (Terminal.app)

Steps to Reproduce

  1. Run codex to start an interactive session on Apple Silicon Mac
  2. Use the session normally
  3. Exit the session with Ctrl+C
  4. Check processes: ps aux | grep codex

Expected Behavior

All codex-related processes should terminate cleanly after the session ends.

Actual Behavior

The parent node process exits or becomes idle (S state, 0% CPU), but the child native codex binary continues running at ~99% CPU.
Each
session that is exited leaves behind another runaway process.

Observed state at the time of discovery:

┌───────┬─────────────┬───────┬──────────────────┬──────────────────────┐
│ PID │ State │ CPU% │ Started │ Accumulated CPU Time │
├───────┼─────────────┼───────┼──────────────────┼──────────────────────┤
│ 43103 │ R (Running) │ 98.0% │ 22:25 (prev day) │ 838 min (~14 hrs) │
├───────┼─────────────┼───────┼──────────────────┼──────────────────────┤
│ 46122 │ R (Running) │ 99.1% │ 01:04 │ 690 min (~11.5 hrs) │
├───────┼─────────────┼───────┼──────────────────┼──────────────────────┤
│ 7229 │ R (Running) │ 97.8% │ 12:25 │ 41 min │
└───────┴─────────────┴───────┴──────────────────┴──────────────────────┘

Total CPU waste: ~1,500 minutes across 3 orphaned processes.

Stack Trace (via sample)

A sample of one process (PID 42523) showed:

  • Runtime: Rust with tokio async runtime (8 worker threads)
  • Main thread: Blocked in event loop (_pthread_cond_wait)
  • tokio workers: 7 of 8 blocked on _pthread_cond_wait, 1 active on epoll_wait-equivalent
  • fsevents loop: Actively watching filesystem via CFRunLoopRun → mach_msg
  • reqwest-internal-sync-runtime: HTTP client idle
  • OpenTelemetry.Metrics.PeriodicReader: Waiting on semaphore

Despite appearing idle in the sample, the processes consumed ~99% CPU continuously, suggesting a busy-loop or spin-wait issue —
possibly related to Rosetta translation of the event loop.

Workaround

Manually kill orphaned processes after each session:

pkill -f "codex-darwin-x64"

Possible Root Cause

The codex-darwin-x64 (x86_64) binary is running under Rosetta 2 on an arm64 Mac. The codex-darwin-arm64 variant may not be installed
or
selected. The busy-loop behavior could be a Rosetta-specific issue with the tokio runtime's I/O polling, or a signal handling issue
where SIGINT/SIGHUP from the parent node process is not properly propagated to the native child.

What steps can reproduce the bug?

a

What is the expected behavior?

_No response_

Additional information

_No response_

View original on GitHub ↗

This issue has 1 comment on GitHub. Read the full discussion on GitHub ↗