Windows Codex Desktop appears to trigger sustained kernel pool growth via file/pipe/filter-driver activity
Summary
Codex Desktop on Windows appears to be a repeatable trigger for sustained Windows kernel pool growth during long local sessions.
The retained memory is not primarily ordinary Codex process private memory. Killing the entire Codex process tree released ordinary committed memory, but did not release the accumulated Nonpaged/Paged Pool. The pool growth is concentrated in Windows kernel pool tags associated with file objects, I/O file extensions, token/security objects, and named-pipe activity.
Current evidence suggests a compatibility issue between Codex Desktop's high-volume file/pipe/subprocess/tool activity and the Windows file-filter stack, especially paths involving npfs, fltmgr, and Microsoft Defender's WdFilter. Codex may not be the kernel driver leaking memory directly, but it appears to be the workload that reliably triggers the growth.
User impact
- Normal memory usage after reboot: about 40%.
- After a long Codex session: memory rises toward 60-70%.
- Observed kernel pool during the issue:
- Nonpaged Pool: about 7.6 GB.
- Paged Pool: about 5.1 GB.
Filetag: about 4.3 GB Nonpaged.IoFEtag: about 1.55 GB Nonpaged.Toketag: about 2.5 GB Paged.SeAttag: about 522 MB Paged.SeTltag: about 174 MB Nonpaged.- Closing Codex does not release the accumulated kernel pool.
- Reboot is the only confirmed way to reclaim the already accumulated pool.
Environment
- OS: Windows, transcript reports
Microsoft Windows NT 10.0.26200.0. - Codex Desktop package path observed in process command lines:
C:\Program Files\WindowsApps\OpenAI.Codex_26.623.13972.0_x64__2p2nqsd0c76g0\app\Codex.exeC:\Program Files\WindowsApps\OpenAI.Codex_26.623.13972.0_x64__2p2nqsd0c76g0\app\resources\codex.exe- Codex runtime/tooling paths observed:
...\AppData\Local\OpenAI\Codex\runtimes\cua_node\1b23c930bdf84ed6\bin\node_repl.exe...\.codex\plugins\cache\openai-bundled\chrome\latest\extension-host\windows\x64\extension-host.exe- Microsoft Defender status during the test:
AMServiceEnabled=TrueAntivirusEnabled=TrueRealTimeProtectionEnabled=TrueBehaviorMonitorEnabled=TrueIoavProtectionEnabled=TrueOnAccessProtectionEnabled=True
What was ruled out
Not simply accumulating cmd.exe processes
The initial suspicion was that Codex might be accumulating cmd.exe processes. Live process inspection did not support that as the primary issue. The problematic memory is in kernel pool tags, not ordinary process memory.
Killing Codex releases ordinary memory but not kernel pool
A detached exit test fully killed the old Codex process tree using taskkill /PID <CodexRootPID> /T /F.
Transcript excerpt:
Codex process count: 12
Codex root process count: 1
Closing Codex root processes with taskkill...
taskkill /PID 30120 /T /F
...
No Codex processes remained after taskkill.
Before/after memory snapshot from that Codex-exit test:
| Metric | Before | After | Delta |
| --- | ---: | ---: | ---: |
| Available GB | 11.78 | 13.49 | +1.71 |
| Committed GB | 36.58 | 33.18 | -3.40 |
| Nonpaged Pool GB | 7.63 | 7.62 | -0.01 |
| Paged Pool GB | 5.10 | 5.09 | -0.01 |
Interpretation: Codex process memory was reclaimed, but the accumulated kernel pool was not.
WPR/ETW pool-trace evidence
A WPR Pool.Verbose-style trace was collected while the pool was already high.
Raw ETL size: 39,340,474,368 bytes.
Parsed summary:
EventsSeen=290640421
PoolEventsSeen=127999028
Groups=240099
Tags=957
Elapsed=00:00:56.4593886
During the WPR observation window, tracked tags continued growing:
| Tag | Before | After | Delta |
| --- | ---: | ---: | ---: |
| File Nonpaged MB | 4214.29 | 4220.83 | +6.54 |
| IoFE Nonpaged MB | 1507.35 | 1509.58 | +2.23 |
| Toke Paged MB | 2507.27 | 2513.61 | +6.34 |
| SeAt Paged MB | 519.78 | 521.03 | +1.25 |
| SeTl Nonpaged MB | 172.93 | 173.37 | +0.44 |
Codex-attributed pool activity in the trace
Top Codex/codex process groups from parsed pool events:
| Tag | PID | Process | Type | Net MB | Net count | Notes |
| --- | ---: | --- | --- | ---: | ---: | --- |
| NpFr | 31984 | Codex | 0x10000208 | 185.627 | 6467 | Large named-pipe/file-related growth |
| Obtb | 30120 | Codex | 0x10000001 | 104.273 | 26694 | Object table related |
| NpFR | 31984 | Codex | 0x10000200 | 25.262 | 6467 | Named-pipe/file-related growth |
| NpFr | 31040 | codex | 0x10000208 | 23.678 | 44 | Codex app-server/runtime |
| WtdJ | 30120 | Codex | 0x10000001 | 13.805 | 2966 | Thread/process related workload |
| Thre | 30120 | Codex | 0x00000200 | 10.168 | 2975 | Thread objects |
| File | 30120 | Codex | 0x00000200 | 5.648 | 14807 | File object growth |
| Toke | 30120 | Codex | 0x00000001 | 3.942 | 2227 | Token/security object growth |
| IoFE | 30120 | Codex | 0x00000200 | 2.007 | 29232 | I/O file extension growth |
These values are only from the sampled trace window; the accumulated system-wide pool was much larger.
Stack evidence
A TraceEvent-based parser converted the ETL to ETLX and confirmed call stacks:
HasCallStacks=True
EventsSeen=16392350
MatchedPoolEvents=133442
Groups=1308
Elapsed=00:01:07.9282620
Important stack group summaries:
| Tag | PID | Process | Net MB | Net count | Modules in stack |
| --- | ---: | --- | ---: | ---: | --- |
| NpFr | 31984 | Codex | 43.315 | 1514 | ntoskrnl > npfs > fltmgr |
| NpFr | 30120 | Codex | 8.859 | 12 | ntoskrnl > npfs > fltmgr |
| NpFr | 31040 | codex | 6.643 | 7 | ntoskrnl > npfs > fltmgr |
| NpFR | 31984 | Codex | 5.914 | 1514 | ntoskrnl > npfs > fltmgr |
| File | 30120 | Codex | 1.845 | 4837 | ntoskrnl > ntdll > kernelbase |
| IoFE | 30120 | Codex | 0.517 | 4837 | ntoskrnl > ntdll > kernelbase > kernel32 |
| Toke | 30120 | Codex | 0.312 | 176 | ntoskrnl > WdFilter |
Other modules seen in relevant stack groups include npfs, fltmgr, WdFilter/wdfilter, bindflt, ahcache, chrome, and codex.
Interpretation: the strongest stacks point to named pipes (npfs) and file filter manager (fltmgr), with Defender WdFilter also appearing in token/security-object paths.
Defender exclusion experiment
An elevated test added Defender exclusions for Codex-related application/runtime/workspace paths and observed pool tags for 10 minutes.
Note: the first version of this local test also accidentally added overbroad C:\Windows\system32 and C:\Windows\system32\cmd.exe exclusions. Those should be ignored for product guidance; a cleanup script was prepared locally. The meaningful part of the experiment was excluding Codex-specific paths and processes.
10-minute memory delta after exclusions:
| Metric | Delta |
| --- | ---: |
| Available GB | +0.09 |
| Committed GB | -0.02 |
| Nonpaged Pool GB | +0.01 |
| Paged Pool GB | +0.01 |
Tracked tag deltas after exclusions:
| Tag | Delta Nonpaged MB | Delta Paged MB |
| --- | ---: | ---: |
| File | +4.04 | 0 |
| IoFE | +0.35 | 0 |
| Toke | 0 | +0.09 |
| SeAt | 0 | +0.01 |
| SeTl | +0.01 | 0 |
Interpretation: the short observation period was much more stable after Defender exclusions, but this does not reclaim previously accumulated kernel pool.
Hypothesis
Codex Desktop's workload appears to trigger sustained kernel pool growth through a combination of:
- High-frequency file open/read/write/stat activity.
- High-frequency subprocess creation (
cmd.exe, PowerShell,node_repl.exe, plugin/tool servers). - Named pipe traffic between the desktop app, runtimes, and tool/plugin hosts.
- File filter/minifilter interaction, including Microsoft Defender
WdFilter,fltmgr,bindflt, and possibly cache/compatibility filters such asahcache.
The leak/retention is likely in the Windows kernel/filter-driver path rather than in Codex user-mode heap directly. However, Codex is the repeatable trigger and should either reduce the triggering pattern or document/ship mitigations.
Suggested investigation
- Reproduce on Windows with Defender real-time protection enabled and Codex Desktop running tool-heavy sessions for multiple hours or days.
- Track
PoolNonpagedBytes,PoolPagedBytes, and pool tagsFile,IoFE,Toke,SeAt,SeTl,NpFr,NpFR,Obtb. - Run WPR with pool stack capture while Codex is active.
- Inspect named-pipe and file-handle lifecycle in Codex Desktop,
codex.exe,node_repl.exe, and extension/plugin hosts. - Look for unbounded creation of short-lived pipes, file handles, threads, tokens, or child processes.
- Test whether batching/reusing tool runtimes and named pipes reduces
NpFr/NpFRandFile/IoFEpressure. - Test with Defender exclusions for Codex-specific paths/processes to confirm the
WdFilterinteraction. - Consider official Windows/Defender guidance for Codex Desktop exclusions if this interaction is expected.
- Add a Codex diagnostic bundle command that captures process tree, handle counts, pool tags, and relevant WPR profiles.
Suggested product mitigations
- Reuse long-lived runtime/tool processes where possible instead of creating many short-lived shell/node/PowerShell processes.
- Reuse named pipes or IPC channels where possible.
- Reduce file-system polling/scanning of Codex workspace/plugin/runtime directories.
- Avoid placing high-churn transient files under locations aggressively scanned by Defender when possible.
- Provide a documented, narrow Defender exclusion list for Codex Desktop on Windows.
- Add a warning/diagnostic when kernel pool tags grow unusually during long Codex sessions.
I have parsed CSV summaries and a 39 GB raw ETL locally and can provide them if maintainers want specific files.
6 Comments
Potential duplicates detected. Please review them and close your issue if it is a duplicate.
Powered by Codex Action
Follow-up: current Codex build, ETW process storm, and live kernel object ownership
I reproduced the same failure mode on a current Codex Desktop build and collected additional ETW, PoolMon, and live-kernel-dump evidence.
Environment
26200.8655, x64OpenAI.Codex_26.707.3748.0_x64__2p2nqsd0c76g02.55.0.windows.221.23.6.614Codex-triggered process churn
During a 35-second WPR/ETW process trace, there were 846 new processes:
The trace contained 263 direct
ChatGPT.exe -> git.exestarts. (ChatGPT.exeis the desktop process image in this Codex package.) The dominant repeated command was:The selected workspace root contained an empty
.gitdirectory with noHEAD. Renaming that directory out of the workspace stopped the Git storm in subsequent samples (git.execount remained zero). This is consistent with #29110, #28631, and #26812: a failed repository-root probe appears to be retried without effective negative-result caching or backoff.Exited process objects were retained
Stopping the Git storm prevented the catastrophic creation rate, but did not reclaim objects already retained during that boot. At approximately 45 minutes uptime, with only 245 active processes and zero live
git.exeprocesses, PoolMon showed:A reboot reclaimed the accumulated pool. With the empty
.gitmitigation still in place:Proc Diff=1,367,Frees=1, zerogit.exe.Proc Diff=2,187,Frees=3, zerogit.exe.This reduced the growth rate by roughly 98%, but process-object frees still remained close to zero, so the retention path was mitigated rather than fully resolved.
Live kernel dump: sampled holder was Kaspersky
A live kernel dump captured one exited
git.exeprocess object created byChatGPT.exe. Debugger analysis showed:!findhandlefound both handles in Kaspersky'savp.exe.!obtraceincluded Kaspersky process-notify/filter stacks involvingarkmon,klflt,klgse, andklif.The large
+32768value visible in the object trace is Windows process-object reference bias, not 32,768 leaked references. The sampled evidence proves thatavp.exewas the immediate external handle holder for this exited process object at capture time. It does not prove that Kaspersky permanently leaks every object, or that Kaspersky alone is the root cause.The evidence supports an interaction model:
Proc/MiP2/PsInallocations.After adding narrow Kaspersky trusted-application rules, a controlled run of 64 immediate-exit
cmd.exechildren still producedProc AllocDelta=145,FreeDelta=0; Kaspersky's Process-type handle count increased by only 7. The rules reduced the workload but did not restore timely reclamation.Requested fix and diagnostics
Please investigate the Windows desktop repository-discovery loop and:
.gitdirectory as a bounded error instead of continuously spawninggit.exe.rev-parse --show-toplevelrequests per workspace.This evidence also connects the Git/process reports in #26812, #29110, and #30926 with the Kaspersky interaction reported in #17955. It suggests a cross-product amplification path rather than a simple user-mode heap leak or a single-vendor failure.
I have a 3.6 GB live kernel dump plus sanitized PoolMon, ETW, and debugger summaries. I will not attach the raw dump publicly because it may contain sensitive kernel memory, but I can provide selected sanitized artifacts or use a private upload channel if an OpenAI maintainer requests them.
Additional reproduction: Browser/CUA runtime mitigation stopped observed pool growth
I reproduced the kernel-pool growth on Windows with the current Desktop package:
OpenAI.Codex_26.707.3748.0_x64__2p2nqsd0c76g0A reboot reclaimed the accumulated pool:
Additional local observation
The Codex configuration had:
browser@openai-bundledinstalled and enablednode_repl.exeprocessesSKY_CUA_NATIVE_PIPE=1turn-endednotify hook launchingcodex-computer-use.exeSimply editing generated
config.tomlentries was not persistent: Codex recreated the file at the next startup and re-injected the Browser/node_replconfiguration.The persistent mitigation used was:
I also removed the generated
turn-endednotify entry and terminated only the three Codex-runtimenode_repl.exeprocesses.Verification after mitigation:
browser@openai-bundled: not installednode_repl.exe: 0codex-computer-use.exe: 0No Microsoft Defender exclusion was added.
This is a short observation window and does not prove that Browser/CUA is the sole cause. The workspace still contains an empty/invalid
.gitdirectory, so the repository-discovery behavior described in the other follow-up remains a possible concurrent trigger. However, the result suggests that Browser/CUAnode_replnative-pipe activity and the per-turncodex-computer-use.exehook are worth isolating in a controlled reproduction.It may also be useful for Codex to avoid silently re-injecting removed generated MCP/notify configuration, or to expose a single supported “safe mode” that disables Browser/CUA runtimes and high-churn background tooling while diagnosing Windows pool growth.
I am seeing what appears to be the same issue on Windows 11.
In-app Codex feedback session ID:
019ee25c-ca99-7c93-b434-1997d09c7386
Environment:
Observed behavior:
Controlled observations:
Example measurement with Codex active and OneDrive closed:
Example measurement after stopping Codex / ChatGPT / OneDrive:
This looks consistent with the issue described here: Codex appears to trigger Windows kernel memory / pool growth. In my case OneDrive and endpoint protection may amplify the issue, but Codex appears to be the repeatable trigger.
I can reproduce a very similar issue on Windows, and I collected both PoolMon data and a targeted WPR trace.
System details:
OpenAI.Codex_26.707.9564.0_x64ChatGPT.exe32.0.31021.5001sysdiag.sysversion6.0.0.3At the time of diagnosis:
The largest PoolMon tags included:
FMfn: 4,292.67 MiBFile: 1,658.58 MiBNtfc: 659.58 MiBIoNm: 593.96 MiBIoFE: 576.68 MiBSQSF: 440.14 MiBOver a 36.82-minute PoolMon interval,
FMfnincreased by 68.26 MiB, or approximately 1.85 MiB/minute.I then captured a targeted 155-second WPR trace containing allocation and free stacks for
FMfn. The resulting ETL was only 207 MiB.The trace contained:
FMfnallocationsFMfnfreesFMfngrowth: +6.607 MiBThe most significant finding was extreme Git process churn:
git.exeprocess lifetimes in approximately 155 secondsChatGPT.exeprocessThe most frequent commands were:
rev-parse --show-toplevelconfig --null --get core.fsmonitorstatus,read-tree,ls-files, and related repository queriesRepresentative allocation stacks included:
and:
Within the top 100 outstanding stack groups:
sysdiag.sysbindflt.sysbfs.sysThese categories overlap because several filters appear in the same call path. This does not prove that Huorong is solely responsible, but it strongly suggests that Codex’s abnormal Git/file-query workload is being amplified or retained by the Windows minifilter stack.
I did not find evidence that the GPU was the primary source. During the same 36.82-minute interval:
003D: 0 MiB growthDAL3: +1.70 MiBVi54: +1.00 MiBCould the Codex team investigate why the desktop app is launching thousands of short-lived Git probes and whether repository-state polling can be debounced, cached, or disabled? On this machine, the Git process storm appears to be the workload trigger, while the file-filter stack is where the kernel-pool allocations accumulate.
I can provide sanitized PoolMon snapshots and stack reports. The raw ETL contains local paths and command lines, so I would prefer not to upload it publicly.
Follow-up: current Windows build,
NtFCallocations map almost 1:1 to minifilter failures and all outstanding stacks includebindflt.sysI reproduced the same kernel-pool growth on a newer Codex Desktop build and collected a focused WPR Pool + Minifilter trace. This reproduction is especially concentrated in the nonpaged
NtFCtag.Environment
OpenAI.Codex_26.715.4045.0_x64ChatGPT.exe26200.8875, x64bindflt.sys:10.0.26100.865532.0.21032.800232.0.16.1047User impact and live growth
Before reboot, nonpaged pool reached approximately 52.7 GB. Normal user-mode process memory did not account for it.
After reboot and reopening Codex Desktop, an 11-second counter sample showed:
The CLI was present during the same session but idle; the active Codex Desktop
ChatGPT.exeprocess was the workload correlated with the growth.WPR capture
The trace was collected with:
Trace summary:
NtFCownershipThe focused pool-event parser found:
Therefore, 128,634 of 128,636 outstanding
NtFCallocations created during the trace were attributed to the Codex Desktop main process.The
128,626MinifilterPreOpFailureevents are almost a one-to-one match with the128,634outstanding Codex-attributedNtFCallocations.Stack evidence
The ETL was converted to ETLX and all 128,636 outstanding
NtFCallocations were inspected with call stacks.Every outstanding allocation stack contained:
The common file-filter chain was:
Notably, none of the outstanding
NtFCstacks contained:WdFilter.sysbfs.sysCldFlt.sysThis does not prove that
bindflt.sysalone is the root cause. It does show that, in this reproduction, Codex Desktop's Chromium/main-process file activity is the repeatable trigger and the retainedNtFCallocations all pass through the Windows Bind Filter path.Unsafe diagnostic result: unloading
bindfltcaused a bugcheckAs a diagnostic only,
fltmc unload bindfltwas attempted. The system immediately became unstable and restarted with:After reboot,
bindfltreturned to its normalRUNNING / AUTO_STARTstate.I do not recommend unloading or disabling
bindfltas a workaround. I am including this only because it further indicates active dependency on this filter path and because maintainers should avoid suggesting that mitigation.Requested investigation
Please investigate:
bindflt.sysexposes a lifecycle bug that is not triggered by the CLI.Diagnostic artifacts
Available locally:
I have not uploaded the raw ETL or dump publicly because they may contain local paths or process memory. I can provide sanitized summaries or use a private upload channel if requested.