[Windows Desktop] Full-process PowerShell/WMI polling remains in 26.721.4979.0 and contributes to system-wide input lag

Resolved 💬 11 comments Opened Jul 30, 2026 by Sceleratis Closed Aug 5, 2026
💡 Likely answer: A maintainer (github-actions[bot], contributor) responded on this thread — see the highlighted reply below.
\[!IMPORTANT\]<br>Creating this to better document and consolidate information for an on-going issue that multiple people have reported. Including additional information about suspected causes and what has been done locally to a patched copy of the desktop app to temporarily resolve the issue on my machine.

What version of the Codex App are you using (From “About Codex” dialog)?

26.721.41059

What subscription do you have?

Pro

What platform is your computer?

Microsoft Windows NT 10.0.26200.0 x64

What issue are you seeing?

Summary

Codex Desktop on Windows can cause intermittent mouse and keyboard stalls across the entire operating system, not only inside the app.

The strongest confirmed contributor is repeated full-machine process discovery launched by the Desktop app through short-lived PowerShell processes and WMI/CIM queries.

The current Store package tested here, OpenAI.Codex 26.721.4979.0, still contains and executes these process-inventory paths.

A 30-second stock capture recorded five Desktop-descendant WMI-inventory PowerShell starts, seven total PowerShell starts, 79 conhost.exe starts, and 172 captured descendant starts.

A narrowly patched copy of the same current runtime recorded zero WMI-inventory PowerShell starts in two separate 30-second runs. It retained the same 13 live runtime processes and remained alive in both runs.

An earlier controlled A/B on package 26.707.3351.0 isolated the command-registry discovery path. Suppressing that path reduced:

  • WMI PowerShell starts from 26 to 0 per minute;
  • paired WMI conhost.exe starts from 26 to 0;
  • maximum low-level mouse-event delivery delay from 234 ms to 16 ms;
  • events delayed over 100 ms from 1 to 0.

That is direct intervention evidence that Desktop-generated process discovery materially contributes to the system-wide stalls.

Automatic repository-origin discovery is a second process-amplification path. In a matched A/B on 26.707.3351.0, suppressing it reduced git.exe starts from 206 to 22 in about 47 seconds.

The current local mitigation is an unsupported diagnostic patch, not a production-ready fix. It disables optional discovery features in a copied runtime while leaving the signed Microsoft Store package untouched.

This issue consolidates the root cause, current patch, measurements, and related public reports into one tracker.

The earlier reports are linked below rather than restated as separate claims. This report adds current-build reproduction, the 26.721.4979.0 patch port, fresh validation, and one cross-issue technical map not present in a single existing issue.

Affected environment

<!-- linear:table-colwidths:400,400 -->
| Item | Value |
| -- | -- |
| Platform | Windows 11 x64 |
| Distribution | Microsoft Store/MSIX |
| Current affected package | OpenAI.Codex 26.721.4979.0 |
| Internal app version | 26.721.41059 |
| Internal build | 5848 |
| Desktop executable | ChatGPT.exe |
| Executable file version | 150.0.7871.128 |
| Current-build validation date | 2026-07-27 |
| Earlier causal A/B build | 26.707.3351.0 |

Independent reports show the same query families across older and newer releases. Examples range from 26.506.3741.0 in [#22912](<https://github.com/openai/codex/issues/22912>) through the 26.715 reports listed below.

User-visible impact
  • Mouse movement and typing intermittently stall across unrelated Windows applications.
  • The problem is often most visible during launch, command execution, project refresh, or task switching.
  • Local captures show PowerShell, console-host, WMI, and Git activity. Related public reports also correlate some events with Defender or cleanup-process spikes.
  • Some reports observe continued background activity after the app window closes, until the remaining Desktop process tree is terminated.
  • The symptom is not limited to renderer frame rate. A low-level Windows hook measured delayed event delivery before downstream application rendering.
Actual behavior

Several independent Desktop paths can request overlapping global process snapshots. Each snapshot creates process-launch, console-host, WMI-provider, serialization, and teardown work.

Other paths can concurrently fan out Git commands or repeatedly attempt process cleanup. Together, these can create sustained machine-wide contention and visible input stalls.

What steps can reproduce the bug?

The exact trigger is state-dependent, but the underlying process-inventory work is directly observable.

  1. Launch the Windows Desktop app.
  2. Open a project and use a task that executes local commands.
  3. Observe the full ChatGPT.exe descendant tree with Process Monitor, Process Explorer, System Informer, ETW, or a native Toolhelp-based ancestry monitor.
  4. Record process command lines and WMI Provider Host activity.
  5. Watch for short-lived powershell.exe, conhost.exe, git.exe, and taskkill.exe children or descendants.
  6. Check whether mouse or keyboard delivery stalls in another foreground application at the same time.

The two characteristic WMI query families are:

Get-CimInstance Win32_Process |
  Select-Object ProcessId, ParentProcessId |
  ConvertTo-Json -Depth 2

and:

$cpuByPid = @{}
Get-CimInstance Win32_PerfFormattedData_PerfProc_Process |
  ForEach-Object {
    $cpuByPid[[int]$_.IDProcess] = [double]$_.PercentProcessorTime
  }
Get-CimInstance Win32_Process

The second command also collects process details such as command line and working-set size.

What is the expected behavior?

Routine Desktop operation should not repeatedly launch PowerShell to enumerate every process on the machine.

Process tracking should be scoped to app-owned children, coalesced, cached, bounded, and implemented without degrading input delivery in unrelated applications.

Repository metadata work should be proportional to unique repository roots, not the number of submitted working directories or UI refreshes.

Additional information

Technical root cause

The packaged Electron application contains several separate process-discovery consumers. They do not share one cached, single-flight snapshot.

1\. Telemetry/process-snapshot worker

The bundled worker is:

.vite/build/child-process-snapshot-worker.js

The current call path is:

30-second focused heartbeat, renderer-ready event, or renderer snapshot request
  -> Electron sampler collectSnapshotFields()
  -> addChildProcessFields()
  -> child-process-snapshot-worker.js
  -> Win32_Process parent scan
  -> Win32_PerfFormattedData_PerfProc_Process
     plus Win32_Process detail scan

The current main bundle has a 30-second heartbeat and a 5-second minimum gate for non-heartbeat triggers.

On Windows, the worker launches fresh PowerShell processes for both WMI query families.

PID detail work is chunked, so one snapshot can involve one parent scan and one or more detail scans.

2\. Shared process-subtree discovery

The current shared bundle is:

.vite/build/src-BPbHdvxe.js

In package 26.721.4979.0, the module-exported seam is:

export Tn
  -> internal IW
  -> full Win32_Process parent scan
  -> filtered descendant resolution
  -> performance/process-detail WMI scan

This implementation is separate from the telemetry worker and can independently execute the same global inventory work.

3\. Chat-process registry private dependencies

The current registry class captures the original implementations in a private dependency object:

$Y = {
  listDetachedProcessCandidates: LW,
  listProcessSubtrees: IW
}

Its mutation path is:

registry upsert() / complete()
  -> resolve a missing osPid
  -> retry at approximately 0, 100, 300, and 600 ms
  -> privately captured listProcessSubtrees()
  -> detached-process fallback if still unmatched
  -> PowerShell/WMI

Each subtree attempt can execute two PowerShell/WMI inventory commands. The final detached fallback can execute another.

Source inspection therefore permits up to nine PowerShell/WMI inventory invocations for one unmatched mutation. A command may invoke the mutation at both start and completion.

Replacing only the exported process-snapshot function does not affect these privately captured references.

This registry path produced the strongest controlled process and input-delivery A/B.

4\. Chrome native-host cleanup

The current release contains another process-inventory consumer:

export gn
  -> internal BK
  -> default Windows listProcesses()
  -> detached-process inventory
  -> WMI

Its confirmation loop uses delays of approximately 0, 100, 200, 400, and 800 ms.

Internal callers can retain the original dependency rather than looking up the public export. An export-only override is therefore insufficient for the current build.

This is another global process-inventory and cleanup consumer.

The broader taskkill.exe/conhost.exe reports may reflect a related lifecycle defect, but this trace does not establish that BK/gn launches taskkill.exe. The verified cleanup here uses process.kill.

5\. Automatic Git-origin discovery

The Git worker accepts lists of directories and resolves them concurrently:

git-origins worker request
  -> normalize and deduplicate submitted directories
  -> Promise.all(directory resolutions)
  -> repository metadata and origin lookup

Representative commands include:

git rev-parse --show-toplevel
git rev-parse --git-common-dir
git config --get remote.origin.url
git config --null --get core.fsmonitor

Multiple UI directory sets, malformed or empty .git directories, and cache invalidation can recreate the fan-out.

This is a separate contributor to process churn. It should not be conflated with the command-registry WMI path that produced the direct input-latency A/B.

Why an app-local defect affects the whole system

The local captures directly demonstrate operating-system-wide work rather than only renderer work:

  • repeated PowerShell and console-host creation and teardown;
  • global WMI process and performance inventory;
  • concurrent Git and console-host creation;
  • process-tree construction and JSON serialization;
  • delayed low-level input-hook delivery.

The linked reports separately document WMI quota exhaustion, Defender load, taskkill storms, DWM degradation, and kernel-resource pressure.

Those reports show the breadth of the Windows process-lifecycle problem. They are not all locally reproduced mechanisms in the current experiment.

The historical input probe measured delay at the low-level Windows hook callback. That places the observed stall before any affected foreground application renders the input.

Current diagnostic patch
\[!WARNING\]<br>This is an unsupported diagnostic mitigation for confirming and containing the bug. It is build-specific, reduces functionality, and is not a substitute for an upstream fix.

The patch is applied to a copied runtime. The signed Store installation remains untouched.

Current build-specific mapping

The minified identifiers changed between releases. For 26.721.4979.0, the exact ordinal, case-sensitive mappings are:

<!-- linear:table-colwidths:266,266,266 -->
| Behavior | Internal symbol | Export |
| -- | -- | -- |
| Process-subtree discovery | IW | Tn |
| Chat-process registry | tX | en |
| Chrome native-host cleanup | BK | gn |

These identifiers must be rediscovered for every build.

There are important case hazards in this release:

  • lowercase kn exports xW, a browser/Chrome configuration object;
  • lowercase rn exports wY, an instruction-builder function;
  • uppercase Gn is unrelated to lowercase gn.

Reusing the older build's mappings, or comparing names case-insensitively, can silently patch unrelated functionality.

Packaging procedure
  1. Leave the signed Store package untouched.
  2. Copy the entire matching Store app directory into a separate versioned runtime.
  3. Archive and extract resources/app.asar.
  4. Preserve the original JavaScript files beside or outside the extracted source.
  5. Install three wrapper files implementing the six mitigation behaviors below.
  6. Repack the ASAR with the matching native-module layout.
  7. Overlay the new app.asar and app.asar.unpacked into the copied runtime.
  8. Verify that all non-ASAR executables and resources still match the same Store release.
  9. Do not run the Store runtime and copied runtime simultaneously because they share application state.

The repack command used for the current build was:

npx.cmd --yes '@electron/asar@4.2.0' pack <source> <output> `
  --unpack-dir '{node_modules/better-sqlite3,node_modules/node-pty}' `
  --unpack '**/*.node'

The matching app.asar.unpacked directory must remain beside the ASAR.

Do not combine a new ASAR with an older executable or runtime. Electron, native-module ABI, Codex binaries, and packaged resources may all change between releases.

Patch 1: return an empty optional telemetry snapshot

Replace the telemetry child-process worker while preserving its successful response contract:

parentPort.postMessage({ type: "ok", value: [] });

This prevents that worker from launching either PowerShell/WMI query family.

Patch 2: intercept only automatic git-origins

Preserve the original Git worker as worker-original.js.

Install a wrapper at the expected worker.js path before loading the original. Intercept only messages satisfying all three conditions:

workerData.workerId === "git"
message.type === "worker-request"
message.request.method === "git-origins"

Return a successful result containing:

{ origins: [] }

The response must retain the original request identifier and worker protocol. Delegate every other request and event to worker-original.js.

Patch 3: suppress the exported shared process snapshot

Preserve the current shared module as:

.vite/build/src-original-BPbHdvxe.js

Leave a wrapper at the original src-BPbHdvxe.js path.

On Windows, replace only export Tn with:

const emptyProcessSnapshot = async () => [];

Pass every unrelated export through unchanged.

Patch 4: stop registry mutations from scanning

On Windows, replace export en with a subclass of the original registry.

Inherited reads remain available. Only the two mutation methods that trigger private process discovery become no-ops:

class NonScanningChatProcessRegistry extends original.en {
  async upsert() {}
  async complete() {}
}

This intentionally reduces command-lifecycle registry persistence.

Patch 5: inject an empty process list into native-host cleanup

Wrap export gn and call the original implementation with its normal options plus a replacement nested dependency:

original.gn({
  ...options,
  dependencies: {
    ...options?.dependencies,
    listProcesses: async () => [],
  },
});

All other cleanup checks remain in the original function.

This prevents this exported cleanup path from performing a global process inventory.

Patch 6: cover private module closures during initialization

Exports alone do not cover private references captured while the original shared module initializes.

Temporarily wrap child_process.execFile only while importing src-original-BPbHdvxe.js.

The interception predicate requires all of the following:

executable basename is powershell.exe
command contains Get-CimInstance
command contains Win32_Process
  or Win32_PerfFormattedData_PerfProc_Process

Matching commands receive JSON []. Unrelated child-process calls delegate to the original execFile.

The wrapper must implement the correct util.promisify.custom behavior because the preserved module uses a promisified form.

Restore the global child_process.execFile in a finally block immediately after module initialization.

The preserved module captures the promisified wrapper during initialization. Its private helpers therefore retain the narrow filter for later calls after the global execFile has been restored.

The effective shared-module behavior is:

Tn -> async () => []
en -> non-scanning registry subclass
gn -> original cleanup with listProcesses: async () => []
unrelated exports -> original implementation
private WMI helpers captured during original-module initialization
  -> matching calls made later return JSON []
unrelated execFile calls -> original implementation
Validation
Original causal A/B: package 26.707.3351.0

The registry comparison used identical diagnostic settings for all other patched paths. The only changed variable was whether registry mutations retained WMI discovery.

One-minute process-ancestry comparison

<!-- linear:table-colwidths:266,266,266 -->
| Measurement | Registry WMI active | Registry WMI suppressed |
| -- | -- | -- |
| Desktop-descendant WMI PowerShell starts | 26 | 0 |
| Paired WMI conhost.exe starts | 26 | 0 |
| Time with at least one WMI helper alive | 94.8% | 0% |
| Desktop core-process restarts | 0 | 0 |

Low-level input-delivery comparison

<!-- linear:table-colwidths:266,266,266 -->
| Measurement | Registry WMI active | Registry WMI suppressed |
| -- | -- | -- |
| Mouse events | 4,022 | 8,317 |
| Maximum hook-delivery delay | 234 ms | 16 ms |
| Events delayed over 16 ms | 2 | 0 |
| Events delayed over 100 ms | 1 | 0 |

The probe compared each event timestamp with the time its WH_MOUSE_LL or WH_KEYBOARD_LL callback ran. It measured delivery to the hook, not renderer latency.

Matched Git-origin comparison

<!-- linear:table-colwidths:266,266,266 -->
| Measurement | Stock | Origin discovery suppressed |
| -- | -- | -- |
| git.exe starts | 206 | 22 |
| conhost.exe starts | 185 | 55 |
| All observed process starts | 496 | 165 |

The launch windows were approximately 47 seconds. A separate ancestry capture confirmed that the large Git burst descended from Desktop.

Current patch port: package 26.721.4979.0

Two patched 30-second process-ancestry runs were compared with a stock 30-second run:

<!-- linear:table-colwidths:200,200,200,200 -->
| Measurement | Stock | Patched run 1 | Patched run 2 |
| -- | -- | -- | -- |
| WMI-inventory PowerShell starts | 5 | 0 | 0 |
| Automatic git-origins probes | 0 | 0 | 0 |
| All PowerShell starts | 7 | 1 | 1 |
| conhost.exe starts | 79 | 31 | 25 |
| Captured descendant starts | 172 | 93 | 74 |
| Live runtime processes | 13 | 13 | 13 |
| Desktop remained alive | Yes | Yes | Yes |

After each probe, the harness closed the main window, force-stopped any remaining copied-runtime processes, and verified that zero remained.

The current stock window did not happen to contain an automatic Git-origin probe. Current Git coverage therefore combines a worker contract test with the earlier matched process A/B.

The three current captures were separate launch windows without a matched active-command workload.

Total descendant and conhost.exe counts are descriptive, not precise performance deltas. The deterministic pass criteria were zero classified WMI inventories and zero automatic origin probes, backed by contract tests.

The current tests prove that the identified WMI and automatic-origin hot paths were absent during the measured windows. They do not prove that every source of Desktop lag or every cleanup loop is fixed.

Patch verification gates

The current build passed:

  • JavaScript syntax checks for wrappers and preserved originals;
  • exact telemetry-worker response-contract checks;
  • git-origins interception and non-origin delegation tests;
  • behavior checks for Tn, en, and gn;
  • restoration checks for global child_process.execFile;
  • guards proving kn, rn, and Gn remain identical to their original unrelated exports;
  • packed-ASAR extraction comparisons;
  • native-module layout checks;
  • comparisons of ten critical executable, Codex, Electron, and rg.exe resources against the matching Store payload.

Only the intended app.asar and matching app.asar.unpacked overlay differed from the copied Store runtime.

At final verification, the live Store ASAR still matched the archived source ASAR. The Store installation was not modified.

Limitations and functional tradeoffs
  • All consumers of the telemetry worker snapshot or Tn receive no descendants. This includes Desktop child-process observation and its process-list/kill UI.
  • Registry insertion/update and completion/removal through upsert() and complete() are disabled.
  • Automatic repository-origin discovery returns no origins. Repository grouping and project metadata may therefore be less accurate.
  • Chrome native-host cleanup cannot discover candidate processes through global inventory. Stale native-host or extension-host candidates may not be terminated through that path.
  • The patch does not prove that every taskkill.exe cleanup path is disabled.
  • Ordinary Git operations, non-git-origins worker traffic, and unrelated PowerShell or child-process calls remain enabled.
  • The copied runtime does not receive Store updates and must be rebuilt for each release.
  • The minified bundle names and exports are build-specific and must never be carried forward without source inspection.
Evidentiary limits
  • The current build refresh includes direct process-creation validation but no new low-level input-latency A/B.
  • The 234 ms to 16 ms result is a controlled single-run comparison on the earlier affected build, not a long-duration benchmark.
  • The current stock capture contained no automatic origin probes, so the current run is not a fresh Git process-count A/B.
  • The Toolhelp ancestry monitor sampled every 25 ms. It can miss very short-lived processes.
  • Command-line classification can miss a process that exits before its command line is read. The reported counts are lower bounds.
  • The low-level hook probe measured delivery to its callback, not downstream app rendering.
  • Elevated ETW was not used to isolate the final Windows kernel contention point.
  • Not every PowerShell, Git, console-host, or cleanup process is necessarily unnecessary.

The causal conclusion is based on source tracing, process ancestry, a narrow intervention, and symptom-boundary input measurements.

Recommended upstream fix

The affected features can be preserved without routine global PowerShell/WMI scans.

  1. Track app-owned processes at the shared spawn boundary.
  2. Route all process-discovery consumers through one replaceable dependency.
  3. If enumeration is unavoidable, use one native snapshot, cache it briefly, coalesce concurrent requests, and cancel superseded work.
  4. Do not retry optional process telemetry when discovery is unavailable.
  5. Make PID resolution bounded and event-driven instead of performing several global scans at command start and completion.
  6. Separate process observation from cleanup. Cleanup should act only on explicitly owned PIDs with start-time or process-handle validation.
  7. Canonicalize and deduplicate repository paths before origin lookup.
  8. Cache origin data per repository root, use bounded concurrency, and cancel stale requests.
  9. Ignore malformed or empty .git markers rather than repeatedly probing them.
  10. Keep process inventory behind one testable interface so private closures cannot bypass throttling or caching.
Suggested Windows regression budgets
  • Zero routine Desktop-descendant PowerShell commands containing Win32_Process or Win32_PerfFormattedData_PerfProc_Process.
  • Process starts proportional to unique repository roots, not submitted directory count.
  • At most one in-flight process snapshot for all consumers.
  • No unbounded taskkill.exe or conhost.exe loops.
  • No measurable low-level mouse or keyboard delivery regression during active command traffic.
  • Bounded process cleanup after app exit.
Requested outcome

Please use this issue as a canonical tracker for the Windows process-inventory and process-fan-out defect family.

The requested product outcomes are:

  • replace routine PowerShell/WMI process inventory with bounded, app-owned process tracking;
  • coalesce and cache any unavoidable native snapshots;
  • make process cleanup ownership-aware and bounded;
  • bound and cache repository-origin discovery;
  • add Windows process-creation and low-level input regression tests;
  • provide a supported feature flag or temporary mitigation until the upstream implementation ships.

I can provide sanitized command-line captures, ancestry data, wrapper-contract tests, and additional measurements if maintainers need them.

Related public reports

The index below was checked against GitHub on 2026-07-28.

It includes the original report, every issue linked from that report, the existing discussion, direct WMI/Git/cleanup reports found in a fresh search, and a separate group of similar symptoms.

The categories matter. The first four groups contain direct mechanism or close process-lifecycle evidence. The final groups are included for context and are not presented as proof of the same cause.

Primary history

<!-- linear:table-colwidths:266,266,266 -->
| Link | State | Relevance |
| -- | -- | -- |
| [#28855 — original Windows system-input-lag report](<https://github.com/openai/codex/issues/28855>) | Open | Reports whole-system mouse and typing stalls beginning with Desktop 26.611.8604.0. |
| [Discussion #29949 — Windows Desktop performance visibility thread](<https://github.com/openai/codex/discussions/29949>) | Public discussion | Community thread collecting Windows performance reports. |
| [Existing root-cause and patch comment](<https://github.com/openai/codex/discussions/29949#discussioncomment-17597798>) | Public comment | Earlier full writeup and original causal A/B on 26.707.3351.0. |

Direct WMI and process-snapshot evidence

<!-- linear:table-colwidths:266,266,266 -->
| Link | State | Relevance |
| -- | -- | -- |
| [#22912 — Electron sampler WMI snapshot failures and freezes](<https://github.com/openai/codex/issues/22912>) | Open | Shows both WMI query families in Desktop 26.506.3741.0. |
| [#25453 — PowerShell full-process polling](<https://github.com/openai/codex/issues/25453>) | Open | Measures 23 PowerShell starts in 30.05 seconds on 26.527.31326. |
| [#29499 — WMI Provider Host CPU and system freezes](<https://github.com/openai/codex/issues/29499>) | Open | Reports WMI CPU near 50% and recurring mouse freezes on 26.616.51431. |
| [#32562 — starting a task saturates WMI Provider Host](<https://github.com/openai/codex/issues/32562>) | Open | Confirms both query families in 26.707.3748.0. |
| [#33875 — WMI and Defender load on the home screen](<https://github.com/openai/codex/issues/33875>) | Open | Reproduces before opening a project on 26.715.2305.0. |
| [#33940 — sustained WMI CPU and system stutter](<https://github.com/openai/codex/issues/33940>) | Closed as duplicate of openai/codex#33875 | Reports repeated Win32_Process scans and mouse stalls on 26.715.31251. |
| [#34014 — Desktop WMI saturation while VS Code remains normal](<https://github.com/openai/codex/issues/34014>) | Open | Isolates the behavior to Desktop on 26.715.12143. |
| [#34050 — repeated PowerShell creation and hard freeze](<https://github.com/openai/codex/issues/34050>) | Open | Reports hundreds of launches and WMI quota failures on 26.715.4045.0. |
| [#34158 — system-wide mouse stutter with sampler queries](<https://github.com/openai/codex/issues/34158>) | Open | Stutter persists until the remaining process tree is killed on 26.715.4045.0. |
| [#34580 — sampler retries WMI snapshots indefinitely](<https://github.com/openai/codex/issues/34580>) | Open | Identifies missing backoff/single-flight behavior in 26.715.8383.0. |
| [#34592 — WMI loop spawns about ten helpers per second](<https://github.com/openai/codex/issues/34592>) | Open | Measures 235 helpers in 25 seconds on 26.715.7063.0. |
| [#34666 — WMI/Defender CPU and mouse stutter stop on full exit](<https://github.com/openai/codex/issues/34666>) | Open | Correlated lifecycle evidence on 26.715.8383.0; the exact provider is not isolated. |
| [#34854 — Git/PowerShell churn drives WMI and Defender CPU](<https://github.com/openai/codex/issues/34854>) | Open | Recent mixed-path reproduction on 26.715.10079.0. |
| [#34879 — launch saturates CPU through WMI Provider Host](<https://github.com/openai/codex/issues/34879>) | Open | Recent all-core reproduction on 26.715.10079.0. |

Cleanup-loop and taskkill.exe/conhost.exe evidence

<!-- linear:table-colwidths:266,266,266 -->
| Link | State | Relevance |
| -- | -- | -- |
| [#33776 — hundreds of taskkill/conhost children, WMI storms, and DWM degradation](<https://github.com/openai/codex/issues/33776>) | Open | Reports 987 failed WMI queries in package 26.707.12708.0. |
| [#33778 — taskkill/conhost storm during local tool execution](<https://github.com/openai/codex/issues/33778>) | Open | Counts 178 taskkill and 197 conhost processes on 26.715.2305.0. |
| [#34001 — built-in agent cleanup runaway loop](<https://github.com/openai/codex/issues/34001>) | Open | Reports roughly 300 each of taskkill and conhost on 26.715.4045.0. |
| [#34025 — cold launch creates 300+ cleanup helpers](<https://github.com/openai/codex/issues/34025>) | Open | Storm begins after launch without a tool call on 26.715.3651.0. |
| [#34260 — cleanup storm exhausts WMI](<https://github.com/openai/codex/issues/34260>) | Open | Reports 457 taskkill, 473 conhost, and 1,388 total processes on 26.715.4045.0. |
| [#34302 — stuck cleanup helpers cause system-wide UI delays](<https://github.com/openai/codex/issues/34302>) | Open | Reports taskkill/conhost buildup on 26.715.31925. |
| [#34548 — mixed Git/WMI/taskkill storm and disk saturation](<https://github.com/openai/codex/issues/34548>) | Closed | Mixed process-storm report on 26.715.8383.0. |
| [#34691 — sustained WMI CPU with cleanup helpers](<https://github.com/openai/codex/issues/34691>) | Open | A 20-second sample finds 408/410 taskkill helpers as direct Desktop children. |
| [#34929 — process-manager polling launches 12–15 taskkill processes per second](<https://github.com/openai/codex/issues/34929>) | Open | Measures 226 launches in 15 idle seconds on 26.715.10079.0. |

These reports establish a close process-lifecycle failure family. The local patch covers known snapshot, registry, origin, and native-host inventory paths, but this issue does not claim it disables every cleanup path.

Git-origin, repository-discovery, and kernel-pressure evidence

<!-- linear:table-colwidths:266,266,266 -->
| Link | State | Relevance |
| -- | -- | -- |
| [#17229 — repeated Git status and orphan Git/conhost processes](<https://github.com/openai/codex/issues/17229>) | Open | Early report of the Windows Git/conhost family in 26.325.3894.0. |
| [#16786 — repeated Git creation with NTFS pool growth](<https://github.com/openai/codex/issues/16786>) | Open | Connects Git process churn with Windows kernel-pool pressure. |
| [#20567 — roughly 1,000 Git commands per minute](<https://github.com/openai/codex/issues/20567>) | Open | Independent high-rate Git process report. |
| [#29858 — continuous Git in a non-repository workspace](<https://github.com/openai/codex/issues/29858>) | Open | Git/conhost creation stops after the directory becomes a valid repository. |
| [#29911 — empty .git directories trigger repeated origin scanning](<https://github.com/openai/codex/issues/29911>) | Open | Explicit git-origins, Git config, console-host, and Defender loop. |
| [#30926 — Git process creation drives kernel Token/Toke growth](<https://github.com/openai/codex/issues/30926>) | Open | ETW captures 263 Desktop-parented Git starts and 55 PowerShell starts in about 55 seconds. |
| [#29436 — persistent kernel-pool growth and system slowdown](<https://github.com/openai/codex/issues/29436>) | Open | Related kernel-pressure report. openai/codex#30926 shows a plausible mechanism for one process-churn variant, not proof that openai/codex#29436 has the same cause. |
| [#29729 — stale Git/process-token objects](<https://github.com/openai/codex/issues/29729>) | Closed as duplicate | Additional report in the same Git/process-token cluster. |
| [#35775 — same-build git-origins storm in the VS Code extension](<https://github.com/openai/codex/issues/35775>) | Open | Non-Desktop corroboration only: internal build 26.721.41059 produced 474 Git and 360 console-host starts in three minutes. |

Similar Windows symptoms without confirmed shared cause

<!-- linear:table-colwidths:266,266,266 -->
| Link | State | Distinction |
| -- | -- | -- |
| [#20214 — frequent freezes and stutters on Windows](<https://github.com/openai/codex/issues/20214>) | Open | Similar in-app freeze/stutter; the reporter says the rest of Windows remains responsive. |
| [#27394 — high CPU after an update](<https://github.com/openai/codex/issues/27394>) | Closed | Similar performance symptom; mechanism not established here. |
| [#28440 — renderer CPU usage](<https://github.com/openai/codex/issues/28440>) | Closed as duplicate | Renderer-focused rather than proven process-inventory work. |
| [#28735 — chat switching and composer lag](<https://github.com/openai/codex/issues/28735>) | Closed | In-app lag without direct evidence of this mechanism. |
| [#29187 — slow Codex thread switching on Windows](<https://github.com/openai/codex/issues/29187>) | Open | Similar transition-time symptom. |
| [#29281 — idle CPU/GPU activity](<https://github.com/openai/codex/issues/29281>) | Open | Similar background pressure, without an established shared cause. |
| [#29543 — first-typing freeze](<https://github.com/openai/codex/issues/29543>) | Open | Similar input symptom, without direct WMI attribution. |
| [#29590 — previous-task loading stalls](<https://github.com/openai/codex/issues/29590>) | Open | Similar UI stall, without direct process-polling evidence. |
| [#29700 — Windows memory growth](<https://github.com/openai/codex/issues/29700>) | Open | Resource-growth report without a confirmed common mechanism. |
| [#29821 — UI stutters during launch and first typing](<https://github.com/openai/codex/issues/29821>) | Open | Reporter observed low WMI usage, so likely a different initialization path. |
| [#33074 — mouse stutter without CPU/disk saturation](<https://github.com/openai/codex/issues/33074>) | Open | Similar symptom, but the reported resource profile differs. |
| [#33258 — cursor jitter when Desktop becomes idle](<https://github.com/openai/codex/issues/33258>) | Open | Evidence points toward DWM composition; reducing Git churn did not remove it. |
| [#33382 — system stutter during task switching](<https://github.com/openai/codex/issues/33382>) | Open | DPC/ISR and crash evidence, not established as WMI polling. |
| [#30389 — kernel-memory retention](<https://github.com/openai/codex/issues/30389>) | Closed | Outcome-level kernel-resource report without direct Git/process evidence. |

Logging and SQLite pressure referenced by the original report

These can cause severe Desktop slowdowns but are not evidence for the WMI/Git mechanism.

<!-- linear:table-colwidths:266,266,266 -->
| Link | State | Distinction |
| -- | -- | -- |
| [#24275 — rapid logs_2.sqlite and WAL growth](<https://github.com/openai/codex/issues/24275>) | Open | macOS logging/storage pressure referenced by the original report. |
| [#27741 — large log database can prevent launch](<https://github.com/openai/codex/issues/27741>) | Open | Database startup failure. |
| [#29177 — SQLite I/O and system stalls](<https://github.com/openai/codex/issues/29177>) | Open | Storage-pressure symptom. |
| [#29463 — TRACE logging despite a warning-level setting](<https://github.com/openai/codex/issues/29463>) | Open | Excess logging rather than process polling. |
| [#29674 — TRACE logging and SSD pressure](<https://github.com/openai/codex/issues/29674>) | Open | Excess write pressure. |
| [#29799 — app-server TRACE and WAL writes](<https://github.com/openai/codex/issues/29799>) | Open | Logging/database write pressure. |
| [#29832 — persistent disk writes after update](<https://github.com/openai/codex/issues/29832>) | Open | Storage activity without proof of this process-discovery path. |

Non-Windows reports linked by the original issue

The original issue also referenced these as broad performance comparisons. They are not part of the Windows WMI/Git causal cluster.

  • [#20547 — Desktop sluggishness after an update](<https://github.com/openai/codex/issues/20547>) — Open
  • [#21326 — macOS renderer CPU and UI lag](<https://github.com/openai/codex/issues/21326>) — Closed
Technical references
  • [Original public root-cause and patch writeup](<https://github.com/openai/codex/discussions/29949#discussioncomment-17597798>)
  • [OpenAI: ChatGPT for Windows](<https://learn.chatgpt.com/docs/windows/windows-app>)
  • [Microsoft: Win32_Process](<https://learn.microsoft.com/en-us/windows/win32/cimwin32prov/win32-process>)
  • [Microsoft: low-level mouse hook event data](<https://learn.microsoft.com/en-us/windows/win32/api/winuser/ns-winuser-msllhookstruct>)
  • [Microsoft: low-level keyboard hook event data](<https://learn.microsoft.com/en-us/windows/win32/api/winuser/ns-winuser-kbdllhookstruct>)
  • [Microsoft: taking a process snapshot with Toolhelp](<https://learn.microsoft.com/en-us/windows/win32/toolhelp/taking-a-snapshot-and-viewing-processes>)
  • [Electron: application distribution](<https://www.electronjs.org/docs/latest/tutorial/application-distribution/>)
  • [Electron: ASAR archives](<https://www.electronjs.org/docs/latest/tutorial/asar-archives>)

View original on GitHub ↗

11 Comments

github-actions[bot] contributor · 28 days ago

Potential duplicates detected. Please review them and close your issue if it is a duplicate.

  • #36025
  • #35314
  • #35827
  • #35301

Powered by Codex Action

Sceleratis · 28 days ago

Consolidating all information for this issue, as well as what was done locally on my machine to produce a patched copy of the desktop app that resolves the system-wide performance impacts. Additional information can likely be found here that is not in existing issues, including direct cause info beyond just describing the issue itself. I have created this issue in the hope that someone at OpenAI will see this, see all of the associated issues that have been reported, all of the information dropped here including the literal "fix" I'm currently using, and will actually do something about it.

There have been multiple versions now, and this has been happening for months. I very much just want to get this resolved.

athan614 · 28 days ago

Same issue on my side, although WMI is no longer observed in task manager to be utilizing a very high percentage of CPU, severe system-wide stalls are still happening when codex is running tasks. It would cause every other program I have running (e.g. Google Chrome) to become unresponsive, and even the ChatGPT app itself. As a result of such, I am unable to use my computer at all when codex is running a task. Consequently, Codex also takes significantly longer to run scientific simulation tasks due to the system-wide stalls.

jungp0 · 26 days ago

Confirmed again on package 26.727.6591.0

This is still present in the current Microsoft Store/MSIX package on Windows.

Environment
  • Package: OpenAI.Codex_26.727.6591.0_x64
  • Platform: Windows x64
  • Distribution: Microsoft Store/MSIX
Observed process creation

During a 45-second capture, Codex launched these short-lived commands:

  • 20 executions of powershell.exe -NoProfile -NonInteractive -Command containing Get-CimInstance Win32_PerfFormattedData_PerfProc_Process plus Win32_Process to collect CPU, command line, working set, and process age.
  • 9 executions containing Get-CimInstance Win32_Process | Select-Object ProcessId,ParentProcessId | ConvertTo-Json to reconstruct the process tree.

The effective cadence was approximately one new PowerShell process every 1–1.5 seconds while the relevant task/process UI was visible. This creates continuous process startup, WMI/CIM, JSON serialization, console-host, and teardown work.

Current package source confirmation

Read-only inspection of the packaged resources/app.asar confirms that the Windows implementation still hard-codes:

execFile("powershell.exe", [
  "-NoProfile",
  "-NonInteractive",
  "-Command",
  // Get-CimInstance ...
])

The implementation selects this path using process.platform === "win32"; the non-Windows branch uses ps. Therefore changing the configured terminal from PowerShell to Git Bash, or changing the SHELL environment variable, does not affect this polling path.

The packaged UI call sites also still configure both process queries at a one-second interval:

chat-processes:  { enabled: featureGate && isVisible && localThread, intervalMs: 1000 }
child-processes: { enabled: above && hasTrackedProcesses, intervalMs: 1000 }

This explains why keeping the task summary/background-process or process-manager UI visible can maintain the polling loop. Hiding that UI appears to be only a partial workaround; it is not a supported global disable switch.

Resource impact

In the same affected installation, accumulated codex-command-runner and node_repl processes were also observed. Terminating the stale processes released approximately 10.8 GB of committed memory. That retention may be a separate lifecycle bug, but it makes the repeated process-enumeration workload substantially more expensive and can push the machine toward a system-wide stall.

Requested fix / temporary mitigation

Please either:

  1. replace the repeated PowerShell/WMI snapshots with native, in-process, app-owned process tracking; or
  2. use one persistent sampler with caching/single-flight behavior; and
  3. provide a supported switch to disable process metrics/process-manager polling until the native fix ships.

A prompt, AGENTS.md, terminal-shell setting, or SHELL override cannot mitigate this because the Desktop bundle invokes powershell.exe directly.

ezgameworkplace · 25 days ago

Reproduced on a newer Windows Desktop build: 26.727.6591.0 (Microsoft Store, x64), on 2026-08-03.

This reproduction matches the full-process PowerShell/WMI sampler path described here.

Observed behavior

The app repeatedly launched:

powershell.exe -NoProfile -NonInteractive -Command ...
Get-CimInstance Win32_PerfFormattedData_PerfProc_Process
Get-CimInstance Win32_Process

The second query selected process metadata including ProcessId, ParentProcessId, CommandLine, WorkingSetSize, CPU percentage, and process age.

Local app-bundle inspection mapped the command to:

  • .vite/build/child-process-snapshot-worker.js
  • the electron-sampler child-process snapshot path

Measurements

  • 221 matching PowerShell sampler launches between 17:26:27 and 17:48:33 (~22 minutes)
  • WMI Operational log: approximately 950 Event ID 5858 failures involving 715 short-lived client PIDs
  • Query breakdown:
  • 846 full Win32_Process snapshots
  • 67 Win32_Process enumerations
  • 19 process-performance enumerations
  • Two large bursts contained 399 and 432 WMI failure events
  • Hot provider host: WmiPrvSE.exe hosting CIMWin32/cimwin32.dll
  • Sampled provider CPU: approximately 665–717% on the Windows per-process counter scale (about 33–36% whole-machine CPU on 20 logical processors)
  • The affected provider reached about 403 MB working set and 158 threads
  • Representative result codes included 0x80041032 and 0x800706BA ("Could not send status to client"), plus memory-quota throttling messages

The PowerShell clients explicitly used -NoProfile, ruling out the user's PowerShell profile as the source.

This looks like the sampler requests overlapping or retrying after WMI slows, creating positive feedback: short-lived clients exit or time out while CIMWin32 continues processing increasingly expensive snapshots.

No username, repository path, session transcript, or raw logs are attached here. A sanitized event summary can be provided if maintainers need more detail.

chess-oai contributor · 23 days ago

thanks for the detailed reports and investigation here: they were really helpful 💖

  • we’ve shipped fixes in 26.730.7989.0 that address some major sources of powershell/wmi storms
  • taskkill.exe can still be started by other process-cleanup paths, and we’re continuing to work on reducing that separately

if you’re still seeing sustained wmi cpu usage or system-wide lag after 26.730.7989.0, please share an updated /feedback id

qbbbbb · 23 days ago

Additional Windows kernel paged-pool / Token evidence on 26.707.3748.0

I reproduced the same Desktop-generated Git and PowerShell/WMI process churn on Windows 11 25H2 (Build 26200.8875), and captured a fresh 20-minute elevated Xperf trace with POOL allocation/free stack walking after a reboot.

Environment:

  • Microsoft Store package: OpenAI.Codex_26.707.3748.0_x64
  • Desktop executable: ChatGPT.exe
  • Windows: 11 25H2, Build 26200.8875
  • Trace duration: 20:03.555
  • Lost ETW buffers/events: 0 / 0

Process-tree results:

  • 19,430 process starts total (~968.6/min)
  • 12,185 git.exe starts (~607.5/min)
  • 6,564 conhost.exe starts (~327.2/min)
  • 11,525 executions of git ... rev-parse --show-toplevel
  • 598 executions of git config --null --get core.fsmonitor
  • 6,053 direct ChatGPT.exe -> git.exe starts
  • 479 Desktop-descendant PowerShell/WMI inventory starts (~23.9/min), comprising:
  • 262 CPU/process detail snapshots using Win32_PerfFormattedData_PerfProc_Process plus Win32_Process
  • 217 parent-process snapshots using Win32_Process

Kernel pool/Token results:

  • Baseline Toke: 1,049,024,256 bytes (1,000.427 MiB)
  • Final Toke: 1,050,068,096 bytes (1,001.423 MiB)
  • Existing Toke allocation difference: approximately 585,000 objects
  • System-wide user-mode Token handles: only 1,670 (0.2854% of the PoolMon Toke object count)
  • Xperf recorded 2,599,564 allocations for Toke+SeAt+SeTd+SeDt during the window
  • The largest outstanding stack family was WMI/RPC/ALPC Token duplication:

SepDuplicateToken -> SepCreateClientSecurityEx / SeCreateClientSecurity -> ALPC/RPC -> fastprox.dll / wbemcore.dll

  • Eight WMI/RPC stack blocks retained 2,334 allocations / 851.1 KiB at trace end.
  • A process-creation Token path through SeSubProcessToken -> PspInitializeProcessSecurity -> NtCreateUserProcess was also present.

A system-wide Token-handle census shows that the roughly 585k Toke objects are overwhelmingly held through kernel references/security contexts rather than ordinary user-mode Token handles. This supplies a kernel-memory impact mechanism in addition to the CPU/input-lag reports: sustained Desktop-generated process, ALPC/RPC, and WMI churn can accumulate approximately 1 GiB of Toke paged pool after boot on this system.

Other-source cross-checks:

  • ASUS framework was visible in five top-100 stack blocks, but only 58 outstanding allocations / 42.4 KiB.
  • Sangfor, Defender, NVIDIA, NTFS, and Filter Manager modules did not appear in the top-100 outstanding Token/security pool stacks.
  • Scheduled tasks and other sampled user-mode sources were orders of magnitude lower than the Desktop Git/WMI rates.

The 2.3 GiB ETL contains local paths and command lines, so I am not attaching it publicly. I can provide a sanitized report or an ETL through a private OpenAI upload channel if maintainers need it.

I see the maintainer note that major WMI sources were addressed in 26.730.7989.0. I will retest this same PoolMon/Xperf workflow after that build is available on this device, with particular attention to whether the Git-origin storm and long-term Toke accumulation are also reduced.

chess-oai contributor · 22 days ago

the powershell/wmi process-snapshot issue here was addressed in 26.730.7989.0 and is tracked in #25453

the separate runaway git.exe launches and kernel token/paged-pool growth are tracked in #30926

Sceleratis · 21 days ago
the powershell/wmi process-snapshot issue here was addressed in 26.730.7989.0 and is tracked in #25453 the separate runaway git.exe launches and kernel token/paged-pool growth are tracked in #30926

The current version on Windows (updated a few minutes ago) seems to be 26.730.61639 according to the app's "About" popup. Was the patch not released yet? Still hitting the same issues with the most recent update as of this morning with severe system-wide performance impact the moment it's opened.

chess-oai contributor · 21 days ago

@Sceleratis sorry for the confusion, we use different version numbers for the msix. you're on the latest version; mind submitting another feedback ID?

jungp0 · 17 days ago

I found it may be caused by the remote connection. I can still reproduce it after running more than 24 hours remotely.