Codex Desktop on Windows leaves Node/MCP helper processes alive until memory pressure makes PC unresponsive
Summary
Codex Desktop on Windows sometimes leaves many Node/MCP/helper processes running after Codex work, which appears to grow memory usage until the PC becomes sluggish or unresponsive. I am not sure whether the trigger is heavy subagent usage, MCP/Node REPL tool usage, or a broader helper lifecycle issue, but Task Manager shows many Node.js JavaScript Runtime and node_repl.exe processes after Codex activity.
This looks similar to the previously reported Windows helper stack issue in #26327, but I am filing a fresh report because the behavior is still visible on Codex Desktop 26.616.3767.0.
Environment
- App: Codex Desktop on Windows
- Codex package:
OpenAI.Codex_26.616.3767.0_x64__2p2nqsd0c76g0 - OS: Microsoft Windows 11 Pro
- OS version/build:
10.0.26200, build26200, 64-bit - Approx. physical memory: 64 GB
- Usage pattern: long-running Codex Desktop work, including multiple threads/subagents and MCP/tool-enabled sessions
Observed behavior
On 2026-06-19 around 06:28 local time, Windows Task Manager filtered for node showed many Codex-related Node processes. The machine was under substantial memory pressure and became difficult to use.
From the screenshots:
- Task Manager showed overall memory around 67-69%.
- Many
Node.js JavaScript Runtimeentries were present. - Several Node processes were using very large memory individually, including approximately:
- 1,448 MB
- 1,197 MB
- 1,054 MB
- 1,010 MB
- 869 MB
- The same filtered view also showed many
node_repl.exeentries. - CPU and disk activity for many of these processes were low, so the issue appears to be retained idle helper processes rather than active work.
A later live diagnostic sample after the system had recovered/settled still showed repeated Codex helper processes under Codex:
Category Count PrivateMB WorkingMB OldestStart
-------- ----- --------- --------- ---------------------
codex_app_server 1 205.5 257.5 2026-06-19 06:44:42
mcp_server_cjs 3 68.3 116.1 2026-06-19 06:45:02
mcp_server_mjs 3 203.1 154.3 2026-06-19 06:45:02
node_repl 4 188.8 254.8 2026-06-19 06:45:02
other_codex_related 11 865.7 894.5
Representative live process command lines included repeated helpers like:
node_repl.exe
node.exe ./mcp/server.mjs --stdio
node.exe ./mcp/server.cjs --stdio
These were all children of the Codex process tree.
Expected behavior
Codex should keep helper process count and memory bounded during normal Desktop usage.
In particular:
- Completed or closed subagents should not leave their MCP/Node REPL/helper processes alive indefinitely.
- MCP stdio servers should be reused or torn down after the owning session/tool/subagent completes.
- Idle helper processes should not accumulate until Windows becomes memory-constrained.
- Users should not need to restart Codex or manually kill Node processes to recover the machine.
Actual behavior
After Codex Desktop usage, Task Manager can show many retained Node/MCP/helper processes. Some of the Node processes remain idle while holding hundreds of MB to more than 1 GB each, creating enough memory pressure that the PC becomes unresponsive.
Suspected trigger
I do not have a minimal isolated reproduction yet. The issue seems correlated with normal Codex Desktop work that uses:
- multiple threads
- subagents
- MCP tools
- Node REPL/tool-backed sessions
Subagent-heavy work may make it worse, but I cannot confirm that it is the only cause.
Related reports
- #26327: Windows accumulates Node REPL/MCP/stdio app-server helper stacks during long multi-thread sessions
- #25015: app-server leaks MCP process stacks for subagents, causing linear memory growth on Linux
- #20883: project-scoped MCP process pool instead of per-session MCP
- #20349: duplicate MCP/helper process trees and multi-GB RSS during UI/debugging workflows
Diagnostic commands used
These PowerShell commands were used to inspect the live process state:
Get-Process node,node_repl -ErrorAction SilentlyContinue |
Select-Object Id,ProcessName,CPU,WorkingSet64,StartTime,Path |
Sort-Object WorkingSet64 -Descending |
Format-Table -AutoSize
Get-CimInstance Win32_Process |
Where-Object { $_.Name -in @('node.exe','node_repl.exe') } |
Select-Object ProcessId,ParentProcessId,Name,CreationDate,CommandLine |
Sort-Object CreationDate |
Format-List
$procInfo = Get-CimInstance Win32_Process |
Where-Object { $_.Name -in @('node.exe','node_repl.exe') -or $_.CommandLine -match 'Codex|codex|mcp|node_repl' }
$perf = @{}
Get-Process | ForEach-Object { $perf[$_.Id] = $_ }
$rows = foreach ($w in $procInfo) {
$p = $perf[[int]$w.ProcessId]
$cmd = [string]$w.CommandLine
$cat =
if ($cmd -match 'node_repl.exe') { 'node_repl' }
elseif ($cmd -match 'mcp/server\.cjs --stdio') { 'mcp_server_cjs' }
elseif ($cmd -match 'mcp/server\.mjs --stdio') { 'mcp_server_mjs' }
elseif ($cmd -match 'app-server') { 'codex_app_server' }
elseif ($w.Name -eq 'node.exe') { 'node_other' }
else { 'other_codex_related' }
[pscustomobject]@{
Category = $cat
Id = $w.ProcessId
PPid = $w.ParentProcessId
PrivateMB = if ($p) { [math]::Round($p.PrivateMemorySize64 / 1MB, 1) } else { 0 }
WorkingMB = if ($p) { [math]::Round($p.WorkingSet64 / 1MB, 1) } else { 0 }
Start = if ($p) { $p.StartTime } else { $null }
}
}
$rows |
Group-Object Category |
ForEach-Object {
[pscustomobject]@{
Category = $_.Name
Count = $_.Count
PrivateMB = [math]::Round(($_.Group | Measure-Object PrivateMB -Sum).Sum, 1)
WorkingMB = [math]::Round(($_.Group | Measure-Object WorkingMB -Sum).Sum, 1)
OldestStart = ($_.Group | Sort-Object Start | Select-Object -First 1).Start
}
} |
Sort-Object Category |
Format-Table -AutoSizeThis issue has 2 comments on GitHub. Read the full discussion on GitHub ↗