Skip to content

Codex Desktop 26.506.31421 main Electron process pegs ~280% CPU on macOS while app-server is idle #22053

Open

Description

@constansino

Codex Desktop 26.506.31421 main Electron process pegs ~280% CPU on macOS while app-server is idle

Summary

On macOS, Codex Desktop 26.506.31421 (Electron 41.2.0) can drive the main Electron process to sustained ~264–285% CPU for many hours while the underlying codex app-server process stays effectively idle (~0–1% CPU). The hot path captured via sample(1) is in libuv stream reads / Node StreamBase JS callbacks with heavy Buffer/ArrayBuffer allocation, which strongly suggests the cost is in the desktop client's IPC/log/history processing rather than in model or backend compute. Restarting the app temporarily clears the main-process pegging but renderers remain unusually busy (~11% / 4.8% / 4.6%).

This appears related to (but distinct from) several existing reports; filing with concrete sample/profile evidence in case it helps narrow the root cause.

Environment

  • Codex Desktop: 26.506.31421 (CFBundleVersion 2620)
  • Electron: 41.2.0 (from crashpad annotation)
  • OS: macOS 26.4.1 (25E253), Darwin 25.4.0
  • Hardware: Mac mini, Apple M4, 10 cores, 16 GB RAM
  • ~/.codex/sessions: 596 MB, with individual rollout JSONL files of 178M, 65M, 64M, 62M, 46M, 23M

Observed behavior

Live process snapshot before restart (uptime of main process ~23h38m):

Process CPU RSS
Codex.app/Contents/MacOS/Codex (main, PID 665) 264–285% 1.35–1.52 GB
Codex Helper (GPU) 16–24% —
Codex Helper (Renderer, one of several) 13–21% ~1.9 GB footprint
codex app-server 0.1–1.3% —

After a full app restart:

  • Main process drops near idle.
  • Renderers still show abnormal steady-state activity (~11%, 4.8%, 4.6%) without user interaction.

High-signal evidence

sample(1) of the main process shows the hot path concentrated in Electron/Node's local stream pipeline:

uv__io_poll
  -> node::LibuvStreamWrap::OnUvRead
    -> node::StreamBase::CallJSOnreadMethod
      -> V8 / JS frames
        -> heavy Buffer / ArrayBuffer allocation
        -> _platform_memmove, __bzero

Concurrent log patterns (repeating at high frequency):

  • AppServerConnection response routing for thread/list, skills/list, mcpServerStatus/list.
  • browser-session-registry IAB_LIFECYCLE duplicate route captures.
  • Received turn/started for unknown conversation.
  • Repeated git status / git rev-parse probes against saved workspace roots; several roots are Git repos with "No commits yet on main" / no HEAD, causing git rev-parse to return exit code 128 in a tight loop.

Local samples available (no secrets):

  • /tmp/codex-main-665.sample.txt
  • /tmp/codex-renderer-1485.sample.txt
  • /tmp/codex-gpu-975.sample.txt

Why this looks client-side, not model/backend compute

  • codex app-server CPU is ~0–1% throughout, while the Electron main process is at ~280%. If the cost were model/tool execution, the app-server (or a tool subprocess) would show it.
  • The sampled hot stack is purely libuv stream read → Node StreamBase JS callbacks → Buffer allocations and memmove/bzero, i.e. IPC/stream-decode work in the desktop client.
  • Memory footprint and uptime correlate: the longer the app runs and the larger ~/.codex/sessions grows, the worse it gets; restart resets main-process CPU.
  • Log volume is dominated by client-side housekeeping (sidebar lists, lifecycle dedupe, git polling) rather than turn execution.

Possible contributing factors / related issues

These look plausibly connected; not claiming any are the root cause:

Expected behavior

  • Idle/steady-state main-process CPU should be low (single digits) when no turn is active, regardless of session-history size or how long the app has been running.
  • Workspace roots without a Git HEAD should not trigger a tight loop of git rev-parse failures; failed probes should back off or be cached.
  • Sidebar list endpoints (thread/list, skills/list, mcpServerStatus/list) should not generate sustained stream traffic sufficient to peg the Node event loop.
  • Duplicate IAB_LIFECYCLE route captures and turn/started for unknown conversation warnings should not occur in steady state.

Attachments available

Happy to share on request:

  • sample(1) output for main, renderer, and GPU helper processes (paths above).
  • Redacted excerpts of the AppServerConnection / browser-session-registry / git-probe log loops.
  • ls -lhS ~/.codex/sessions summary (sizes only, no content).

Let me know what additional captures (e.g. --cpuprof of the main process, heap snapshot of a renderer) would be most useful and I can attach them.

Metadata

Metadata

Assignees

No one assigned

    Labels

    appIssues related to the Codex desktop appapp-serverIssues involving app server protocol or interfacesbugSomething isn't workingperformance

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions