Repository navigation
[Windows] Completed subagents leave STDIO MCP Node.js processes running (245 processes / 18 GB) #34658
Description
What version of the Codex App are you using (From “About Codex” dialog)?
Codex Desktop 26.715.8383.0 (x64)
What subscription do you have?
Chatgpt pro
What platform is your computer?
Windows 11 Home, 64-bit, version 10.0.26200 (build 26200)
What issue are you seeing?
Node.js version
Node.js v24.15.0, installed at %ProgramFiles%\nodejs\node.exe
When a Codex task spawns subagents while multiple local STDIO MCP servers are enabled, each subagent starts its own copy of every enabled Node-based MCP server. After a subagent records task_complete, those MCP processes remain alive instead of being stopped.
The process count therefore grows approximately linearly with the number of subagents created during the lifetime of the Codex Desktop process. In the observed session, this reached 245 Node.js processes and approximately 18.3 GB of working-set memory.
What steps can reproduce the bug?
- On Windows, enable several local Node-based STDIO MCP servers. My configuration included:
npx -y @cyanheads/pubmed-mcp-server@latestnpx -y clinicaltrialsgov-mcp-server@latest- a local
cas_journalNode MCP server - Node-based MCP servers bundled with the Data Analytics, Sites, and OpenAI Developers plugins
- Start Codex Desktop.
- Run a task that creates multiple subagents.
- Wait for the subagents to finish and record
task_completein their session transcripts. - Inspect the remaining Node processes and their command lines:
$nodes = Get-CimInstance Win32_Process |
Where-Object Name -EQ 'node.exe'
$nodes |
Group-Object CommandLine |
Sort-Object Count -Descending |
Select-Object Count, Name
$workingSet = Get-Process -Name node -ErrorAction SilentlyContinue |
Measure-Object WorkingSet64 -Sum
[math]::Round($workingSet.Sum / 1GB, 2)- Observe that each new subagent adds another repeated set of MCP processes, but completing the subagent does not reduce the process count.
Expected behavior
When a subagent finishes, Codex should close or dispose of that subagent's STDIO MCP clients and terminate their child processes. Alternatively, MCP clients could be shared or pooled with a bounded lifetime across subagents.
The number of local MCP processes should not continue increasing after subagents complete.
Actual behavior
Each subagent created approximately eight Node processes:
| MCP source | Node processes per subagent | Why |
|---|---|---|
| PubMed MCP | 2 | One npx-cli.js process and one server process |
| ClinicalTrials MCP | 2 | One npx-cli.js process and one server process |
| CAS Journal MCP | 1 | Direct Node server |
| Data Analytics plugin | 1 | Plugin-provided server.cjs |
| Sites plugin | 1 | Plugin-provided server.mjs |
| OpenAI Developers plugin | 1 | Plugin-provided server.mjs |
| Total | 8 | Per subagent/session |
Observed totals:
- 30 repeated MCP process sets × 8 Node processes = 240 Node processes attributable to Codex MCP initialization.
- 5 additional unrelated/orphaned
tests/run_fixture_validators.jsprocesses were present, resulting in 245 Node processes overall. - Total Node working-set memory was approximately 18.3 GB.
- The count remained at 245 across repeated samples several minutes apart.
Evidence that completed subagents retain their MCP processes
- Codex Desktop's
codex.exeprocess started at09:23:19. - MCP process sets were then created repeatedly from
09:23:57through10:19:05. - Their creation timestamps closely matched the creation timestamps of subagent session files.
- 25 inspected subagent transcripts ended with an
event_msgwhose payload type wastask_complete. - The corresponding MCP process sets were still alive after those completion records.
- For one concrete example:
- Subagent and its MCP processes started at
09:26:18. - The subagent recorded
task_completeat09:30:24. - Its CAS Journal MCP process was still alive when checked at
10:24:23.
- Subagent and its MCP processes started at
- Process ancestry showed the MCP processes were direct or indirect descendants of Codex Desktop's
codex.exe(somenpxservers had intermediatecmd.exeandnode.exeprocesses).
Process distribution at the time of capture
| Command | Count | Approx. working set |
|---|---|---|
| PubMed server | 30 | 3,349 MB |
PubMed npx-cli.js |
30 | 2,488 MB |
| ClinicalTrials server | 30 | 3,222 MB |
ClinicalTrials npx-cli.js |
30 | 2,484 MB |
Plugin server.mjs processes |
60 | 3,007 MB |
| CAS Journal server | 30 | 1,912 MB |
Data Analytics server.cjs |
30 | 1,593 MB |
Why this does not appear to be a Node.js process-spawning issue
All 240 MCP-related Node processes followed the same Codex/subagent creation pattern and were launched as descendants of the active Codex Desktop process. Multiple independent MCP implementations remained alive in identical per-subagent groups. This points to the Codex session/MCP manager lifecycle rather than one MCP package spawning copies of itself.
I have not changed Node versions yet, because the multiplication is initiated by Codex when sessions/subagents are created. Testing with another supported Node version may still be useful as a secondary compatibility check.
Impact
- Hundreds of Node processes remain after the related subagent work is complete.
- Memory usage can grow into tens of gigabytes during multi-agent workflows.
- The machine becomes slow and may experience memory pressure or paging.
- Fully restarting Codex is currently the practical way to reset the accumulated MCP processes.
Additional context
The strongest current hypothesis is that each subagent initializes its own MCP manager, but the manager or its STDIO child processes are not disposed when the subagent reaches task_complete.
Additional information
No response
Activity
github-actions commentedon Jul 22, 2026
Potential duplicates detected. Please review them and close your issue if it is a duplicate.
Powered by Codex Action
zhang8630 commentedon Jul 23, 2026
Thanks for the additional reproduction. I see the same behavior: simply creating a new task, before it does any actual work, causes many new Node.js processes to appear. They are repeated instances of the configured MCP servers, so this seems related to MCP servers being started again for each task and not being cleaned up properly afterward.
grtninja commentedon Jul 23, 2026
Independent corroboration from a separate Windows 11 Pro / ChatGPT Pro long-running Codex Desktop session on July 23, 2026:
I did not capture a clean per-command process inventory before restarting, so this is corroborating impact evidence rather than a second exact reproduction of the 245-Node-process count. The visible symptom and recovery pattern match this issue closely: multi-agent/MCP activity accumulates unreaped descendants, memory rises into tens of gigabytes, and restarting Codex is the practical cleanup.
A useful built-in diagnostic would expose, per root thread/subagent: MCP client PID tree, ownership, creation time, task completion time, disposal status, and aggregate working set. Codex should also enforce a bounded process/memory ceiling and terminate orphaned MCP clients after the owning subagent reaches a terminal state.
SergeyPomelov commentedon Aug 16, 2026
Reproduced on Windows with ChatGPT/Codex Desktop 26.810.7004.0 the best flagship vibecoded application.
Task Manager showed 253 ChatGPT processes using 8.1 GB RAM. Shortly afterward, there were 139 node.exe processes using 12.5 GB, mostly repeated MCP servers such as GitLab, Jira, Confluence, and Chrome DevTools.
oski350bpm commentedon Oct 12, 2026
Additional macOS evidence: completed worker runtimes retained for 74 min 44 s
This is a macOS reproduction candidate for the completed-subagent retention reported here, with ordinary desktop-thread shutdown as a positive control. I am adding the prepared report and sanitized logs here rather than opening a duplicate issue. The separate prediction-fork startup behavior is also related to #21984.
Title: Desktop retains completed native-worker tool runtimes; eager MCP initialization also occurs in composer prediction forks
Status: Additional macOS evidence for this completed-subagent lifecycle report. Please investigate lifecycle ownership rather than reducing worker concurrency.
Environment
Actual behavior
Completing a native worker does not appear to release its tool runtime automatically. A uniquely matched launch-time cohort of 6 tool processes was still alive 74 min 44 s after task_complete, under the same live desktop app-server. Classified processes included node_repl, CUA and codex-security. No Shutdown event for that worker was found in the inspected thread-tagged backend logs.
This attribution is based on a uniquely matched birth-second cohort, not explicit PID-to-thread ownership metadata. It demonstrates prolonged post-completion retention; it does not establish an indefinite leak or identify the exact retaining reference.
Ordinary desktop conversations provide a positive control: 5 inactive_thread_unsubscribed events were followed by op.dispatch.shutdown approximately 60 s later. Therefore the report is not claiming all cleanup is absent. The installed desktop 3-hour / maximum-10 inactivity policy applies to eligible owner/history streams, not automatically to all passive native workers.
Separately, 13 automatic composer prediction forks initialized globally enabled integrations even though the user did not open those sessions or use those integrations. All 13 received Shutdown, so this is unnecessary startup churn, not proof that these 13 instances leaked indefinitely.
Observed timeline (UTC, October 12)
The public evidence bundle replaces thread UUIDs with stable aliases, omits local paths/usernames, message bodies, environment variables, resume tokens and full argv. It includes the exact lifecycle timestamps and sanitized process measurements.
Impact and limits of attribution
The screenshot provided by the user in the conversation shows 63.32 GB system swap on a 32 GB Mac. A separate previous-day diagnostic snapshot showed approximately 950 processes in the Codex app family. Following staged removal of selected old tool runtimes, app-family counts eventually fell to about 256 and system swap from 43822.94 to 22289.12 MiB. These are observations from ongoing work, not a controlled A/B test, and system swap cannot be attributed exclusively to Codex.
Project preview servers and the desktop renderer also contributed. A separate local project backend suffered a V8 OOM. Those project problems are being addressed independently; they should not be used to explain away the completed-worker cohort retention.
Reproduction procedure to investigate
These steps are a proposed controlled reproduction of the observed condition, not a guarantee that every completion exhibits it.
Expected behavior / requested fix
Acceptance checks
Completed worker → release → owned tool processes exit; transcript remains readable; later followup works; active siblings retain their runtimes. Ordinary-root positive-control shutdown still works. Deliberately handed-off project previews remain available.
Related public reports, for comparison only:
Sanitized evidence files from codex-lifecycle-evidence.zip are reproduced below in full. Raw local logs are not uploaded.
The earlier temporary screenshot source was unavailable when the bundle was prepared. A new user screenshot reports continued accumulation; its numeric values are transcribed below.
Latest user observation and read-only snapshot
The user reports continued accumulation after a restart. New screenshot: 28.19 GB system swap, 26.76 GB used RAM, 13.3 GB compressed, 84% used. Screenshot time is unknown. These figures do not by themselves attribute swap to Codex or prove a monotonic trend. Project server lifecycle fixes have been merged separately, apply to future launches, and existing previews were deliberately kept running.
Latest sanitized read-only snapshot
{ "captured_utc": "2026-10-12T19:50:10.954315+00:00", "platform": "Darwin 27.0.0 arm64 arm", "worker_cap": 6, "system_swap": "vm.swapusage: total = 32768.00M used = 31937.06M free = 830.94M (encrypted)", "vm_stat": "Mach Virtual Memory Statistics: (page size of 16384 bytes)\nPages free: 1918.\nPages active: 372145.\nPages inactive: 351757.\nPages speculative: 19157.\nPages throttled: 0.\nPages wired down: 481357.\nPages purgeable: 0.\n\"Translation faults\": 1677277674.\nPages copy-on-write: 106591457.\nPages zero filled: 1082218693.\nPages reactivated: 340242201.\nPages purged: 13027144.\nFile-backed pages: 259868.\nAnonymous pages: 483191.\nPages stored in compressor: 1253106.\nPages occupied by compressor: 754428.\nDecompressions: 271505510.\nCompressions: 324064866.\nPageins: 104744290.\nPageouts: 205283.\nSwapins: 3358477.\nSwapouts: 6314987.\n", "app_family_process_count": 778, "user_screenshot": { "swap_gb": 28.19, "used_ram_gb": 26.76, "compressed_gb": 13.3, "memory_percent": 84, "capture_time": "unknown" }, "limitations": [ "family includes active tasks, previews and measurement subprocesses; count does not establish abandonment", "RSS does not attribute compressed/swapped memory or exclusive RAM", "user screenshot and current command measurements are separate observations" ], "mutations": { "existing_process_signals": 0, "server_restarts": 0, "config_changes": 0 }, "desktop_roots": [ 99504 ], "current_desktop_version": { "CFBundleShortVersionString": "26.1007.30912", "CFBundleVersion": "20156" }, "largest_20_family_rss_processes": [ { "pid": 51517, "ppid": 51503, "rss_kib": 2201392, "cpu_percent": 212.6, "elapsed": "00:16", "birth": "Mon Oct 12 21:49:54 2026", "executable": "node" }, { "pid": 99563, "ppid": 99504, "rss_kib": 1377376, "cpu_percent": 29.3, "elapsed": "02:46:21", "birth": "Mon Oct 12 19:03:49 2026", "executable": "Codex (Renderer)" }, { "pid": 99564, "ppid": 99504, "rss_kib": 910512, "cpu_percent": 45.9, "elapsed": "02:46:21", "birth": "Mon Oct 12 19:03:49 2026", "executable": "codex" }, { "pid": 99562, "ppid": 99504, "rss_kib": 461936, "cpu_percent": 4.6, "elapsed": "02:46:21", "birth": "Mon Oct 12 19:03:49 2026", "executable": "Codex (Renderer)" }, { "pid": 99504, "ppid": 1, "rss_kib": 333280, "cpu_percent": 9.3, "elapsed": "02:46:23", "birth": "Mon Oct 12 19:03:47 2026", "executable": "ChatGPT" }, { "pid": 31423, "ppid": 31403, "rss_kib": 149248, "cpu_percent": 0.1, "elapsed": "05:42", "birth": "Mon Oct 12 21:44:28 2026", "executable": "next-server (v16.3.3)" }, { "pid": 30676, "ppid": 67608, "rss_kib": 125952, "cpu_percent": 0.0, "elapsed": "59:54", "birth": "Mon Oct 12 20:50:16 2026", "executable": "node" }, { "pid": 16536, "ppid": 99504, "rss_kib": 118208, "cpu_percent": 0.0, "elapsed": "01:07:50", "birth": "Mon Oct 12 20:42:20 2026", "executable": "Codex (Renderer)" }, { "pid": 96155, "ppid": 99504, "rss_kib": 117216, "cpu_percent": 0.0, "elapsed": "11:54", "birth": "Mon Oct 12 21:38:16 2026", "executable": "Codex (Renderer)" }, { "pid": 68505, "ppid": 51378, "rss_kib": 81136, "cpu_percent": 0.0, "elapsed": "46:31", "birth": "Mon Oct 12 21:03:39 2026", "executable": "Google Chrome" }, { "pid": 46955, "ppid": 99564, "rss_kib": 78064, "cpu_percent": 0.0, "elapsed": "01:17", "birth": "Mon Oct 12 21:48:53 2026", "executable": "npm exec chrome-devtools-mcp@1.6.0" }, { "pid": 8979, "ppid": 99504, "rss_kib": 76800, "cpu_percent": 0.0, "elapsed": "02:43:40", "birth": "Mon Oct 12 19:06:30 2026", "executable": "Codex (Renderer)" }, { "pid": 99846, "ppid": 99504, "rss_kib": 69552, "cpu_percent": 0.0, "elapsed": "02:46:15", "birth": "Mon Oct 12 19:03:55 2026", "executable": "Codex (Renderer)" }, { "pid": 99529, "ppid": 99504, "rss_kib": 67072, "cpu_percent": 13.8, "elapsed": "02:46:23", "birth": "Mon Oct 12 19:03:47 2026", "executable": "Codex (Service)" }, { "pid": 99530, "ppid": 99504, "rss_kib": 57040, "cpu_percent": 0.0, "elapsed": "02:46:23", "birth": "Mon Oct 12 19:03:47 2026", "executable": "Codex (Service)" }, { "pid": 82956, "ppid": 99504, "rss_kib": 50992, "cpu_percent": 0.0, "elapsed": "02:01:43", "birth": "Mon Oct 12 19:48:27 2026", "executable": "Codex (Renderer)" }, { "pid": 3668, "ppid": 99564, "rss_kib": 50192, "cpu_percent": 1.3, "elapsed": "02:45:41", "birth": "Mon Oct 12 19:04:29 2026", "executable": "codex-code-mode-host" }, { "pid": 42815, "ppid": 34659, "rss_kib": 47472, "cpu_percent": 4.1, "elapsed": "24:29", "birth": "Mon Oct 12 21:25:41 2026", "executable": "codex" }, { "pid": 45152, "ppid": 22281, "rss_kib": 46672, "cpu_percent": 0.0, "elapsed": "01:48", "birth": "Mon Oct 12 21:48:22 2026", "executable": "node" }, { "pid": 42813, "ppid": 34659, "rss_kib": 45296, "cpu_percent": 2.4, "elapsed": "24:29", "birth": "Mon Oct 12 21:25:41 2026", "executable": "node" } ] }Original sanitized evidence bundle, reproduced inline
The bundle SHA256 is
c04ac41d53f33192aca67d637df2ec68c78279cdeb2785db4b7d6e3ac99bff8d. The manifest applies to the original archived files; the report above has only its submission status/attachment wording updated.SHA256.json
{ "REPORT.md": "a3c5e9be5bc484880759bd7cff1c8e5d35e37d2fd5c4426c55713fb256ff57c3", "worker-cohorts.json": "ce2c07329f46610e756ce25e55f4cb37b414e457054c9135042cd97575632822", "positive-controls.json": "5884b138ac4403262bb3ba4209b6f3f322c4ff6ad2aa03ac5427d43628d9ed39", "historical-memory.json": "576bd8f550adc2f29d4aa143b28b83fc4416966d600f1b61cdaaec2a118818bf" }REPORT.md
worker-cohorts.json
[ { "worker_thread": "thread-13", "completion": "2026-10-12T13:54:46.127Z", "snapshot_utc": "2026-10-12T15:09:30.488098+00:00", "association": "Birth-second cohort inference, not direct runtime ownership metadata", "matching_live_processes": [ { "pid": 39226, "ppid": 1070, "start": "Mon Oct 12 15:51:32 2026", "etime": "01:17:58", "rss_kib": 7200 }, { "pid": 39228, "ppid": 1070, "start": "Mon Oct 12 15:51:32 2026", "etime": "01:17:58", "rss_kib": 14608 }, { "pid": 39230, "ppid": 1070, "start": "Mon Oct 12 15:51:32 2026", "etime": "01:17:58", "rss_kib": 13952 }, { "pid": 39231, "ppid": 1070, "start": "Mon Oct 12 15:51:32 2026", "etime": "01:17:58", "rss_kib": 14560 }, { "pid": 39252, "ppid": 1070, "start": "Mon Oct 12 15:51:32 2026", "etime": "01:17:58", "rss_kib": 15504 }, { "pid": 39279, "ppid": 39230, "start": "Mon Oct 12 15:51:32 2026", "etime": "01:17:58", "rss_kib": 7200 } ] }, { "worker_thread": "thread-14", "completion": "2026-10-12T14:04:44.688Z", "snapshot_utc": "2026-10-12T15:09:30.488098+00:00", "association": "Birth-second cohort inference, not direct runtime ownership metadata", "matching_live_processes": [ { "pid": 53179, "ppid": 1070, "start": "Mon Oct 12 15:54:54 2026", "etime": "01:14:36", "rss_kib": 15456 } ] } ]positive-controls.json
[ { "id": "thread-1", "desktop_unsubscribe": { "line": 1624, "text": "2026-10-12T14:58:33.120Z info [electron-message-handler] inactive_thread_unsubscribed conversationId=thread-1 rendererWebContentsId=1 rendererWindowAppearance=primary rendererWindowFocused=true rendererWindowId=1 rendererWindowVisible=true status=unsubscribed" }, "app_server_shutdown": [ { "utc": "2026-10-12T13:42:38.215354+00:00", "target": "codex_core::session::handlers", "body": "session_loop{thread_id=thread-1}: Submission sub=Submission { id: \"thread-2\", op: Shutdown, turn_extension_init: None, trace: None, parent_turn_id: None, root_turn_id: None, residency_guard: None }" }, { "utc": "2026-10-12T14:59:33.100827+00:00", "target": "codex_core::session::handlers", "body": "session_loop{thread_id=thread-1}: Submission sub=Submission { id: \"thread-3\", op: Shutdown, turn_extension_init: None, trace: None, parent_turn_id: None, root_turn_id: None, residency_guard: None }" }, { "utc": "2026-10-12T14:59:33.102281+00:00", "target": "codex_core::session::handlers", "body": "session_loop{thread_id=thread-1}:submission_dispatch{otel.name=\"op.dispatch.shutdown\" submission.id=\"thread-3\" codex.op=\"shutdown\"}: Shutting down Codex instance" } ], "prior_ableton_matches": [ { "pid": 4495, "birth": "2026-10-12T13:45:47+00:00", "absent_now": true }, { "pid": 4832, "birth": "2026-10-12T13:45:49+00:00", "absent_now": true } ] }, { "id": "thread-4", "desktop_unsubscribe": { "line": 1812, "text": "2026-10-12T14:59:06.043Z info [electron-message-handler] inactive_thread_unsubscribed conversationId=thread-4 rendererWebContentsId=1 rendererWindowAppearance=primary rendererWindowFocused=true rendererWindowId=1 rendererWindowVisible=true status=unsubscribed" }, "app_server_shutdown": [ { "utc": "2026-10-12T13:42:37.076237+00:00", "target": "codex_core::session::handlers", "body": "session_loop{thread_id=thread-4}: Submission sub=Submission { id: \"thread-5\", op: Shutdown, turn_extension_init: None, trace: None, parent_turn_id: None, root_turn_id: None, residency_guard: None }" }, { "utc": "2026-10-12T15:00:06.022654+00:00", "target": "codex_core::session::handlers", "body": "session_loop{thread_id=thread-4}: Submission sub=Submission { id: \"thread-6\", op: Shutdown, turn_extension_init: None, trace: None, parent_turn_id: None, root_turn_id: None, residency_guard: None }" }, { "utc": "2026-10-12T15:00:06.023768+00:00", "target": "codex_core::session::handlers", "body": "session_loop{thread_id=thread-4}:submission_dispatch{otel.name=\"op.dispatch.shutdown\" submission.id=\"thread-6\" codex.op=\"shutdown\"}: Shutting down Codex instance" } ], "prior_ableton_matches": [ { "pid": 4832, "birth": "2026-10-12T13:45:49+00:00", "absent_now": true } ] }, { "id": "thread-7", "desktop_unsubscribe": { "line": 21759, "text": "2026-10-12T14:18:04.328Z info [electron-message-handler] inactive_thread_unsubscribed conversationId=thread-7 rendererWebContentsId=1 rendererWindowAppearance=primary rendererWindowFocused=true rendererWindowId=1 rendererWindowVisible=true status=unsubscribed" }, "app_server_shutdown": [ { "utc": "2026-10-12T14:19:04.325733+00:00", "target": "codex_core::session::handlers", "body": "session_loop{thread_id=thread-7}: Submission sub=Submission { id: \"thread-8\", op: Shutdown, turn_extension_init: None, trace: None, parent_turn_id: None, root_turn_id: None, residency_guard: None }" }, { "utc": "2026-10-12T14:19:04.328921+00:00", "target": "codex_core::session::handlers", "body": "session_loop{thread_id=thread-7}:submission_dispatch{otel.name=\"op.dispatch.shutdown\" submission.id=\"thread-8\" codex.op=\"shutdown\"}: Shutting down Codex instance" } ], "prior_ableton_matches": [ { "pid": 1871, "birth": "2026-10-12T13:45:02+00:00", "absent_now": true }, { "pid": 1928, "birth": "2026-10-12T13:45:02+00:00", "absent_now": true }, { "pid": 2195, "birth": "2026-10-12T13:45:03+00:00", "absent_now": true } ] }, { "id": "thread-9", "desktop_unsubscribe": { "line": 25027, "text": "2026-10-12T14:29:27.837Z info [electron-message-handler] inactive_thread_unsubscribed conversationId=thread-9 rendererWebContentsId=1 rendererWindowAppearance=primary rendererWindowFocused=true rendererWindowId=1 rendererWindowVisible=true status=unsubscribed" }, "app_server_shutdown": [ { "utc": "2026-10-12T14:30:27.833268+00:00", "target": "codex_core::session::handlers", "body": "session_loop{thread_id=thread-9}: Submission sub=Submission { id: \"thread-10\", op: Shutdown, turn_extension_init: None, trace: None, parent_turn_id: None, root_turn_id: None, residency_guard: None }" }, { "utc": "2026-10-12T14:30:27.836886+00:00", "target": "codex_core::session::handlers", "body": "session_loop{thread_id=thread-9}:submission_dispatch{otel.name=\"op.dispatch.shutdown\" submission.id=\"thread-10\" codex.op=\"shutdown\"}: Shutting down Codex instance" } ], "prior_ableton_matches": [ { "pid": 2195, "birth": "2026-10-12T13:45:03+00:00", "absent_now": true } ] }, { "id": "thread-11", "desktop_unsubscribe": { "line": 25068, "text": "2026-10-12T14:29:52.496Z info [electron-message-handler] inactive_thread_unsubscribed conversationId=thread-11 rendererWebContentsId=1 rendererWindowAppearance=primary rendererWindowFocused=true rendererWindowId=1 rendererWindowVisible=true status=unsubscribed" }, "app_server_shutdown": [ { "utc": "2026-10-12T14:30:52.500898+00:00", "target": "codex_core::session::handlers", "body": "session_loop{thread_id=thread-11}: Submission sub=Submission { id: \"thread-12\", op: Shutdown, turn_extension_init: None, trace: None, parent_turn_id: None, root_turn_id: None, residency_guard: None }" }, { "utc": "2026-10-12T14:30:52.503998+00:00", "target": "codex_core::session::handlers", "body": "session_loop{thread_id=thread-11}:submission_dispatch{otel.name=\"op.dispatch.shutdown\" submission.id=\"thread-12\" codex.op=\"shutdown\"}: Shutting down Codex instance" } ], "prior_ableton_matches": [ { "pid": 3805, "birth": "2026-10-12T13:45:41+00:00", "absent_now": true }, { "pid": 4088, "birth": "2026-10-12T13:45:44+00:00", "absent_now": true } ] } ]historical-memory.json
{ "before": { "line": 36, "swap_mib": 43822.94, "system_processes": 1870, "threads": 16242, "pressure_level": 2, "app_family_approx": 950, "largest_renderer_top_mem_mib": 4425, "largest_renderer_peak_cpu_percent_of_one_core": 205.7, "flow_preview_top_mem_mib": 4008, "zr_preview_top_mem_mib": 2680 }, "after": { "line": 404, "swap_mib": 22289.12, "system_processes": 1198, "threads": 10182, "cpu_idle_percent": 0.3, "app_family_approx": 256 }, "limitations": [ "top MEM footprint and ps RSS are different accounting measures; do not sum them as exclusive RAM", "before and after snapshots include ongoing unrelated work; not a controlled test", "swap is system-wide; cleanup benefit does not attribute all swap to one process family" ] }Follow-up: supported manual archival releases completed runtimes
We have now verified a safe manual workaround on the installed desktop build: target an idle completed session using the supported
set_thread_archivedaction. This preserves the transcript in the archive and lets the backend resolve resource ownership instead of guessing PID ownership.Bulk readback: 37 sessions (34 native workers, 3 idle older root conversations), with 37 explicit
op.dispatch.shutdownevents, 37 teardown records statinghad_active_turn=false, nohad_active_turn=true, and 37 final API statesnotLoaded. All 37 archived transcripts remain available. Worktree owners, scheduled/pinned tasks, unfinished goals, active/pending turns, active descendants and preview owners were excluded. No manual PID signals, server restarts or configuration changes were made; concurrency remains 6 and all 9 protected preview process identities were preserved.Observed app-family counts fell from 852 before the batch to 570 afterwards. System swap was 37360.75 MiB earlier, reached 25815.25 MiB during cleanup, and was 27656 MiB at 20:28:18 UTC. The final kernel pressure level was normal, but swap I/O continued while other active conversations worked. These are concurrent observations, not a controlled attribution of all system swap or all exits to this batch.
This corrects the earlier evidence boundary: a supported manual archive/unload path exists and demonstrably works. The remaining bug is that
task_completedoes not automatically perform equivalent runtime release; a dedicated close/unload operation preserving normal session-list placement would still be preferable to requiring archival. No automatic reaper or app patch was installed.