Codex Desktop (macOS): renderer OOM crash loop (~5 min) with many concurrent threads — unbounded thread history retention, post-reload refetch storm, 170+ leaked renderer processes
What version of the Codex App are you using (From "About Codex" dialog)?
26.715.72359 (crash evidence below was collected while 26.715.70719 was the running build; both affected). Embedded Codex Framework: 150.0.7871.124.
What subscription do you have?
Pro
What platform is your computer?
Darwin 25.5.0 arm64 arm — macOS 26.5.2 (25F84), Mac16,11 (Mac mini, M4 Pro, 64 GB RAM)
What issue are you seeing?
The main-window renderer process crashes and auto-reloads every ~5 minutes during heavy multi-thread use. The app itself stays up, but the entire window contents disappear and reload as if the app had restarted. Related to #30891 / #31090 / #26362, but filed separately because I have root-cause evidence on the current build: it is an OOM crash loop with three compounding app bugs.
1. Main-window renderer grows to a multi-GB footprint in minutes, then OOM-crashes.
- Crashpad has accumulated 1,187 sidecars in
~/Library/Application Support/Codex/Crashpad/pending/, all{"osarch":"arm64","ptype":"renderer","ver":"150.0.7871.124"}— 66 on 2026-07-22 alone, with gaps clustering at 4–8 minutes during active use. - Watching one cycle live (15 s sampling): fresh renderer reached 1.9 GB RSS at 5m16s of age;
vmmap --summaryshowed anonymous memory (Memory Tag 255, V8/PartitionAlloc) at ~3.4 GB footprint (1.1 GB resident + 2.3 GB swapped); the process died at 9m06s of age and a new Crashpad sidecar appeared within seconds. Crashpad catching it implies an in-process OOM crash, not a jetsam SIGKILL.
2. Post-crash refetch storm makes the loop self-sustaining.
- The replacement renderer was already at 608 MB RSS 13 seconds after spawn — it immediately re-resumes every thread and re-downloads full histories.
- In the electron main-process log, of the last 2,000
AppServerConnection response_routedentries, 1,275 weremethod=thread/turns/list(plusthread/read×108,thread/resume×108). With 10+ active threads whose histories are multi-MB JSON (full delegation transcripts embedded), the renderer re-ingests everything after every reload and sprints back to the OOM ceiling. - After each reload the log fills with
error [electron-message-handler] Received hook/started for unknown conversation …/Conversation state not found …as in-flight events arrive for state the new renderer no longer has.
3. Renderer process leak starves the machine and accelerates the loop.
- At time of capture the app had 172 live
Codex (Renderer)processes totaling 17.8 GB RSS; many were idle for 14+ hours at 24–150 MB each. Whole app family (renderers + services +codex app-server+ cua_node helpers): 24.8 GB RSS on a 64 GB machine. codex app-server(launched with-c features.code_mode_host=true app-server --analytics-default-enable) had 17 h uptime at 4.4 GB RSS and ~180% CPU.- System swap was pinned at 6.9/8 GB and macOS logged a JetsamEvent with
"largestProcess": "codex". The resulting swap pressure makes the main renderer hit allocation failure sooner, tightening the crash interval.
Crash reports have been uploading from this machine via Crashpad throughout (dumps are removed from pending/ after upload; sidecars remain), so the minidumps should be on your backend under ver 150.0.7871.124, arm64, ptype renderer, 2026-07-18 → 2026-07-23.
What steps can reproduce the bug?
- macOS Codex/ChatGPT desktop app, one window.
- Run ~10+ concurrent long-running threads/subagents (large histories, continuous streaming; several used Computer Use / browser automation).
- Leave the window open. Within ~5–10 minutes the window blanks and reloads; repeat indefinitely.
- Observe new
*_sidecar.jsonwithptype: rendererin~/Library/Application Support/Codex/Crashpad/pending/at each reload, andps aux | grep -c "Codex (Renderer)"growing over hours.
What is the expected behavior?
- Renderer memory for thread UIs should be bounded (virtualize/evict off-screen thread history instead of retaining every thread's full turn list in the DOM/JS heap).
- After a renderer reload, resume should not re-download all histories for all threads at once (
thread/turns/liststorm). - Idle renderer processes should be reaped; they currently accumulate without bound (172 after ~15 h).
codex app-servershould not sit at ~180% CPU / 4.4 GB indefinitely.
Additional information
Full quit + relaunch of the app clears the leaked processes and lengthens the interval, but the OOM loop returns once many threads are streaming again. Happy to provide the Crashpad sidecar list, jetsam report excerpts, or run an instrumented build.
6 Comments
Potential duplicates detected. Please review them and close your issue if it is a duplicate.
Powered by Codex Action
Cross-linking supply-side evidence for the refetch storm documented here: in #33786 (and my duplicate #34915, now closed into it) there is a symbolized
sampleprofile of what the app-server does to serve each of thosethread/turns/listrequests — it rebuilds the page by re-parsing the entire rollout JSONL:So the
thread/turns/list×1,275 flood you measured is doubly expensive: the renderer re-ingests full histories (your OOM loop), and the app-server re-deserializes the complete rollout per request (on my machine: two live ~600 MB rollouts → steady ~210–228% CPU in the app-server from the first minute after launch).One data point suggesting the same root defect has a second failure mode: my machine (26.715.72359 build 5718, macOS 26.5.2, arm64) runs few concurrent threads but two very large ones, and Crashpad shows no renderer loop — instead 7 sidecars since 07-18, all
ptype:"browser", ~8–16 h apart, each matching a SIGABRT.ipswith the #34213 signature (node::OOMErrorHandler→v8::ExternalMemoryAccounter::Updateon thegitworker thread). So: many medium threads → renderer OOM loop (this issue); few giant threads → main-process worker OOM. Both sit downstream of unbounded history rehydration, which #33786 measures on the server side.Update: process-lifecycle leak confirmed from a second angle — helpers survive full app quit, some for 4–5 days.
After fully quitting the app (verified: 0
Codex (Renderer)processes, mainChatGPTprocess gone), these were left behind, all reparented to launchd (ppid 1):cua_nodekernel processes (cua_node/bin/node --experimental-vm-modules .../kernel.js), ~0.8 GB RSS combined, with uptimes of up to 5 days 7 hours — i.e. they have been surviving app quits/relaunches for days, not just this session.browser_crashpad_handlerprocesses fromCodex Framework.framework/Versions/150.0.7871.124/Helpers/, including some 5+ days old.So in addition to the renderer accumulation reported above (172 live renderers after ~15 h inside a running session), Computer Use kernels and crashpad handlers are never reaped on app exit either. Expected behavior: quitting the app should terminate or reap its helper process tree.
Quitting did release everything else: ~17.8 GB of renderer RSS and the 4.4 GB / ~180% CPU
app-serverwere reclaimed; system free memory went from 55% to 76%.Update: controlled restart experiment quantifies the causal chain — the renderer-process leak is workload-driven and is what re-arms the OOM loop.
After a full quit (which reclaimed everything per my previous comment), I relaunched and instrumented the fresh session (30 s sampling of RSS/process counts, plus a watcher on Crashpad
pending/).Phase 1 — light load (first hour): main-window renderer survived the entire hour with the same PID. RSS ranged 1.3 → 3.5 GB peak → recovered to 2.5 GB (GC reclaimed >2 GB when streaming paused). System memory 76% free, swap quiet. Renderer count crept 21 → 26 (~5/hour). Zero renderer crashes. So the renderer's memory use is recoverable when the system has headroom — the multi-GB peak alone is survivable.
Phase 2 — agent farm resumed (~2.5 h, ~16 concurrent conversations streaming):
ptype: renderersidecars at 11:04 and 11:54 local), main-window renderer dead after 3.5 h totalSo the measured chain is: concurrent-thread activity → leaked renderer processes accumulate → system memory/swap exhaustion → main renderer can no longer absorb its own 3–3.5 GB peaks → OOM crash →
thread/turns/listrefetch storm rebuilds at ~28 MB/s → repeat every few minutes. Fixing renderer reaping alone would likely break the loop, since Phase 1 shows the renderer survives its peaks when the system has headroom.Separate crash mode captured (distinct bug, happy to file separately): one un-uploaded minidump from this session was not a renderer at all —
~/.codex/computer-use/Codex Computer Use.app/Contents/MacOS/SkyComputerUseServicecrashed with EXC_BAD_ACCESS / KERN_PROTECTION_FAILURE 232 bytes past a 543 KB worker-thread stack limit (stack overflow), on a thread alongsideAXNotificationObserverthreads observing Microsoft Outlook — i.e. unbounded recursion while walking a large accessibility tree. MatchingSkyComputerUseService-*.ipsreports exist from Jul 19/20/22.@zaptrem Thanks — the rollout re-parsing profile slots right into our measurements: the steady ~170–180% app-server CPU we logged (4.4 GB RSS after 17 h) is well explained by re-deserializing complete rollouts for each of the 1,275
thread/turns/listcalls we counted in a 2,000-RPC window.Our setup is the "many medium threads" shape (10–16 concurrent conversations, multi-MB histories each), and every crash sidecar we've inspected is
ptype: "renderer"— nonebrowser— which is consistent with your two-failure-mode split: many medium threads overwhelm the renderer first; few giant threads hit the main-process git worker's external-memory accounting first (#34213). Both downstream of unbounded history rehydration.One addition from our data: rehydration volume alone didn't kill the renderer when the system had headroom (it peaked at 3.5 GB and GC'd back to 1.3 GB during a light-load hour). It's the leaked renderer processes (26 → 159 in 2.5 h under load, 18.6 GB) exhausting system memory that turns the same peaks fatal. So renderer reaping + incremental/paginated turn serving would likely each independently break the loop.
Update: This regression has accelerated with recent Codex Desktop updates. On the current macOS build (26.727.51351), renderer crashes/reloads now recur every 2–3 minutes during active use, making the application nearly unusable. The main app process remains alive while the window blanks and reloads, and Crashpad continues to show renderer failures. This is materially worse than the earlier ~3–5 minute cadence.