Skip to content

[macOS] 1,360 Node processes consume 41 GB and hang WindowServer within 20 minutes of restart #31946

Open

Description

@qingye-lab

Summary

A Codex Desktop MCP/Node lifecycle failure escalated into two system-wide outages on a 16 GB Apple Silicon Mac.

This appears related to #30408, but adds a materially more severe failure mode on the current desktop build: after the first memory-exhaustion restart, the process fleet grew again to 1,360 system-wide Node processes with a 41.32 GiB aggregate footprint in under 20 minutes. WindowServer then failed its userspace watchdog and the computer restarted again.

Environment

  • Desktop bundle: ChatGPT/Codex 26.707.31123
  • Bundle build: 5042
  • Bundled app-server: codex-cli 0.144.0-alpha.4
  • macOS 26.5.1 (25F80)
  • Mac mini, Apple M4
  • Physical memory: 16 GB

First failure: macOS Jetsam evidence

macOS generated two JetsamEvent reports 5 minutes 56 seconds apart. Both reports use a 16,384-byte page size.

Snapshot All Node processes Node in Codex coalition All-Node resident footprint Codex coalition processes Codex coalition resident footprint Free memory
06:20:05 760 755 1,662,363 pages = 25.37 GiB 799 1,895,040 pages = 28.92 GiB 5,445 pages = 85.1 MiB
06:26:01 843 842 1,778,409 pages = 27.14 GiB 881 2,034,698 pages = 31.05 GiB 2,246 pages = 35.1 MiB

In 5 minutes 56 seconds:

  • Node count increased by 83.
  • Codex-coalition process count increased by 82.
  • All-Node resident footprint increased by 1.77 GiB.
  • Codex-coalition resident footprint increased by 2.13 GiB.

A separate Node diagnostic report recorded this ownership chain:

responsibleProc = ChatGPT
coalitionName   = com.openai.codex
parentProc      = node

At 06:26 the system compressor occupied 9.40 GiB and represented 50.99 GiB of uncompressed system-wide pages. That compressor value is system-wide and is not attributed entirely to Codex.

The machine was manually restarted at 06:32:18 after becoming unusable.

Second failure after restart

A userspace-watchdog spin report captured the system at 06:51:54, approximately 19 minutes 36 seconds after the first restart:

Process family Count Aggregate footprint
Node 1,360 42,312.49 MiB = 41.32 GiB
Codex Renderer 4 945.68 MiB
codex 2 546.63 MiB
ChatGPT 1 340.66 MiB
Codex Service 3 186.44 MiB
node_repl 11 65.05 MiB
WindowServer 1 998.67 MiB

The watchdog report does not contain coalition IDs for each of the 1,360 Node processes, so this report alone cannot prove that every one belonged to Codex. However:

  1. the immediately preceding Jetsam reports attributed 842 of 843 Node processes to the Codex coalition;
  2. live process inspection showed repeated app-server-owned batches of Playwright MCP, Chrome DevTools MCP, XcodeBuildMCP, plugin server.mjs processes, and node_repl;
  3. earlier batches remained alive while later batches appeared.

At 06:52:05 macOS recorded:

monitoring timed out for service
unresponsive work processor(s): WindowServer main thread
42 seconds since last successful checkin

WindowServer was not spinning on CPU: its main thread used about 0.105 seconds of CPU across 11 samples. The sampled stacks were blocked in SkyLight / QuartzCore / kernel paths, with some samples passing through APFS compressed-file reads. This supports a blocked system graphics session, but the unsymbolicated stack is not enough to claim a GPU-driver root cause.

The system restarted again at 06:55:24.

Reproduction observations

During tool-enabled Codex activity, repeated process batches included:

npm exec @playwright/mcp@latest
npm exec chrome-devtools-mcp@latest
npm exec xcodebuildmcp@latest mcp
node ./scripts/start-mcp.mjs
node ./mcp/server.mjs
cua_node/bin/node_repl

The interval included both an initial multi-agent diagnostic phase and later serial tool calls. Therefore the evidence does not isolate concurrency as the sole trigger or prove the exact spawn boundary. It does show that the process fleet remained unbounded across normal tool-host activity.

Expected behavior

MCP and tool-host subprocesses should be reused or torn down at a bounded lifecycle boundary. Their count and memory footprint must remain bounded regardless of thread, subagent, or tool-call volume.

Actual behavior and impact

The Node/MCP process fleet accumulated until macOS had only about 35 MiB of free pages, then reproduced after restart and reached 41.32 GiB of system-wide Node footprint. WindowServer stopped responding and the machine restarted.

This is not merely elevated application RAM. It is a system-availability failure.

Evidence boundaries and privacy

Verified facts above come from macOS JetsamEvent reports, a Node diagnostic report, a WindowServer watchdog report, and a live process-tree snapshot.

Not yet proven:

  • whether each process batch is keyed to a thread, subagent, tool-host instance, or individual tool call;
  • whether every Node process in the second watchdog snapshot belonged to Codex;
  • whether WindowServer was blocked by memory pressure, I/O pressure, or another downstream mechanism.

Project names, usernames, local paths, prompts, and raw session logs are intentionally omitted. Sanitized report excerpts and aggregation commands can be provided privately.

Activity

  1. added
    bugSomething isn't working
    appIssues related to the Codex desktop app
    mcpIssues related to the use of model context protocol (MCP) servers
    on Jul 9, 2026
  2. qingye-lab commented on Jul 9, 2026

    @qingye-lab
    Author

    Thanks — I reviewed #31499, #30753, #31564, and the closely related macOS report #30408.

    This issue may share the same underlying MCP/process-pool lifecycle defect, but it adds a materially different reproduction and impact profile:

    • macOS 26.5.1 on Apple M4 / 16 GB
    • current desktop build 26.707.31123
    • 842 of 843 Node processes attributed to the Codex coalition by macOS Jetsam
    • 27.14 GiB Node footprint and only 35.1 MiB free memory
    • after restart, 1,360 system-wide Node processes / 41.32 GiB within about 20 minutes
    • WindowServer main thread unresponsive for 42 seconds
    • userspace watchdog failure followed by another system restart

    The second watchdog report does not expose per-process coalition IDs, so I am not claiming that all 1,360 Node processes were individually proven Codex-owned. That limitation is documented in the report.

    I am keeping this open for maintainer triage because the linked Windows issues do not contain the macOS Jetsam and WindowServer system-availability failure evidence. If maintainers confirm that this is fully covered by an existing canonical issue, I am happy to consolidate it after this evidence is linked there.

  3. tzimiswcc commented on Aug 10, 2026

    @tzimiswcc

    Additional reproduced outage — macOS graphical-session reset under Codex-owned Node process storm

    I observed another instance of this failure mode on 2026-08-10. This report is text-only and sanitized; no raw logs, project names, usernames, local paths, prompts, or session identifiers are included.

    Environment

    • ChatGPT/Codex Desktop: 26.803.41515
    • Bundle build: 6321
    • Bundled Codex CLI: 0.147.0-alpha.6.5
    • macOS: 26.5.2 (25F84)
    • Mac mini, Apple M4, 16 GB RAM

    Incident classification and timeline

    This was not a kernel panic, power loss, or full machine reboot. Boot history remained continuous from 2026-08-06.

    • 21:45:48 EEST: Codex created an in-app browser/browser-use webview.
    • 21:46:05 and 21:46:10: the Codex process sampler failed while attempting to inspect a list of 200 child PIDs.
    • 21:46:11: the browser operation timed out on a CDP Page.navigate request.
    • 21:47:35.854: the kernel declared the system unhealthy with compressor_exhausted: 1, then began emergency kills for vm-compressor-space-shortage. The same record showed swap_low: 0 and swap_exhausted: 0.
    • 21:49:02.548: launchd recorded WindowServer exit with OS_REASON_WATCHDOG; the report says unresponsive work processor(s): WindowServer main thread and 42 seconds since its last successful check-in.
    • 21:49:06.981: loginwindow recorded Window Server exited, closing down the session immediately and directLogoutReason:WindowServerExited.
    • 21:52:22: Codex launched again under a new PID.

    The user-visible result looked like a restart because the graphical login session was torn down, but the kernel and boot session continued.

    Process evidence at the watchdog boundary

    The WindowServer watchdog stackshot contained:

    • 1,095 distinct live processes named node
    • 1,087 of those had process uptimes between 75 and 180 seconds, placing their creation in a concentrated interval immediately before memory pressure
    • only 8 Node processes were older than 180 seconds

    A Jetsam snapshot 31 seconds later contained:

    • 762 distinct Node PIDs, none marked as previously killed records
    • 761 of 762 assigned to the same Jetsam coalition as ChatGPT, Codex, Codex renderers/services, and the code-mode host
    • approximately 10.3 GiB occupied by the VM compressor
    • about 44 MiB of free pages
    • codex identified as the largest individual process

    The Node executable UUID for 757 records resolved to the user's normal shell-provided Node 20.20.2 executable. This is consistent with Codex-owned descendants inheriting the local shell environment; it does not imply that the user manually launched these processes.

    Correlation and evidence boundary

    The tight timing between the browser-use/CDP failure and the two-minute Node creation burst makes a runaway Codex helper or Node-based tool lifecycle the strongest hypothesis. However, the diagnostic snapshots do not preserve command lines or direct parent PIDs, so this evidence does not prove that browser-use itself was the spawning component.

    What is established:

    1. the Node records were unique live PIDs, not duplicate Jetsam accounting;
    2. nearly all appeared in a short burst;
    3. the surviving fleet was overwhelmingly charged to the Codex app coalition;
    4. VM-compressor exhaustion preceded the WindowServer watchdog;
    5. the result was a forced graphical-session logout, not an app-only crash or kernel reboot.

    Expected behavior remains that Codex-owned tool/helper subprocesses are reused or torn down at a bounded lifecycle boundary and cannot grow into a system-availability failure.

    Sanitized excerpts or aggregation methodology can be provided privately if needed.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    appIssues related to the Codex desktop appbugSomething isn't workingmcpIssues related to the use of model context protocol (MCP) serversperformance

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions