Windows desktop: starting a task can saturate WMI Provider Host CPU

Open 💬 6 comments Opened Jul 12, 2026 by SteffenCarlsen

Summary

Starting a Codex task in the Windows desktop app can drive WMI Provider Host (WmiPrvSE.exe) to approximately 100% CPU.

Environment

  • Codex desktop app: OpenAI.Codex_26.707.3748.0_x64
  • Windows
  • Task mode with the local Windows command host enabled

Reproduction

  1. Start a new Codex task in the desktop app.
  2. Observe CPU in Task Manager shortly after task startup.

Actual result

WmiPrvSE.exe consumes nearly all available CPU during startup.

Live investigation found:

  • A Codex-owned child PowerShell process directly under the desktop app running:

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

  • The WMI Activity operational log recorded repeated full root\\cimv2: Win32_Process enumerations and Win32_PerfFormattedData_PerfProc_Process enumerations around task startup.
  • The hot provider hosts had cimwin32.dll and WmiPerfClass.dll loaded.
  • Many WMI calls ended with 0x80041032 (call cancelled), consistent with short-lived query clients exiting while enumeration is in progress.

The two relevant WMI host processes accumulated roughly 1,950 CPU-seconds during the observed spike before the load subsided.

Expected result

Task startup and command-process tracking should not saturate CPU or require repeated full WMI process/performance enumeration.

Confounder

MedalEncoder.exe was also repeatedly querying Win32_Process WHERE ProcessId = 0; it was closed after diagnosis. It may amplify the symptom, but the Codex process-tree query above was observed directly and is independently present.

Request

Please investigate the Windows process-tree / command-safety tracking path and avoid repeated WMI full-process enumeration where possible (or avoid issuing it concurrently/cancelling it during task startup).

View original on GitHub ↗

6 Comments

H0nok4 · 5 days ago

I reproduced this on the current Microsoft Store package OpenAI.Codex_26.707.9981.0_x64 and traced the same two short-lived PowerShell collectors described here and in #29499:

  • Get-CimInstance Win32_Process | Select-Object ProcessId,ParentProcessId ...
  • Get-CimInstance Win32_PerfFormattedData_PerfProc_Process ...

The PowerShell lifecycle log and Microsoft-Windows-WMI-Activity/Operational correlate the collector PIDs with broad Win32_Process / formatted-performance censuses. The installed app.asar also contains the literal Win32_PerfFormattedData_PerfProc_Process command. This is consistent with the detailed trace in https://github.com/openai/codex/issues/29499#issuecomment-4964194814.

I checked the public repository for a contribution path. The Electron host collector itself is not present here, but #26041 added thread/backgroundTerminals/list specifically so app clients can stop guessing from local process trees. That response already has nullable osPid, cpuPercent, and rssKb fields; today thread_processor.rs hard-codes all three to None.

There appears to be a small public-side follow-up that could at least eliminate PID discovery for app-server-owned background terminals:

  1. Retain the OS PID that codex-utils-pty already obtains when spawning local pipe/PTY children.
  2. Expose it through UnifiedExecProcess and BackgroundTerminalInfo.
  3. Populate ThreadBackgroundTerminal.os_pid for local processes (leave it None for remote exec-server processes until that protocol can supply a host PID).
  4. Add core/app-server tests covering local PID propagation and remote None behavior.

The desktop app would still need an internal change to consume this authoritative PID and to disable/coalesce/cache/back off its broad WMI host snapshots; this public change alone would not address the remaining CPU/RSS collector.

Per docs/contributing.md, I am not opening an unsolicited PR. Would the maintainers like this osPid propagation follow-up to #26041? If so, I would be happy to prepare the focused PR once explicitly invited. If not, that confirms the actionable fix belongs entirely in the private desktop host collector.

adyshimony · 3 days ago

Same here, its killing my cpu
Easy to reprecude, its happening on each load of codex, 70%+, and when running a task in Codex.

<img width="451" height="307" alt="Image" src="https://github.com/user-attachments/assets/0e0e118f-32a7-446d-99a0-78a7ba875a8b" />

suitangxiaoyi · 3 days ago

It doesn't just trigger that; it also launches the ASE service. When I close Codex, both of these processes disappear.
<img width="705" height="115" alt="Image" src="https://github.com/user-attachments/assets/b28d27ae-58fa-43fb-8cba-47735b99e1a9" />

SteffenCarlsen · 2 days ago

Update from the original reporter: I reproduced this again on the newer Microsoft Store package OpenAI.Codex_26.715.2305.0_x64.

  • One WmiPrvSE.exe instance consumed 82.34 CPU-seconds during a 3-second sample on a 32-logical-processor system (about 86% of whole-machine CPU) and had a 409.6 MB working set.
  • WMI-Activity recorded hundreds of failed full Win32_Process enumerations. At 21:27:33 CEST, one second contained 263 0x800706BE (RPC call failed) and 202 0x80041033 (WMI shutting down) results. At 21:29:42, another burst contained 362 0x80041033 results.
  • The preceding events also included 0x80041006 (out of memory), 0x8004100A (critical error), 0x80041013 (provider load failure), and 0x800706BA (RPC server unavailable).
  • A second CIMWin32 provider host started 129 seconds after the first.

<img width="1227" height="160" alt="Image" src="https://github.com/user-attachments/assets/1921605a-96e4-4e01-a6a5-71351dbd5e20" />

This indicates that the collector storm can push the provider into failure/restart behavior, rather than only producing slow or cancelled queries. The WMI status-code meanings are documented in Microsoft's WbemErrorEnum.

SteffenCarlsen · 2 days ago

Temporary workaround using Process Lasso

Until Codex fixes the collector, Process Lasso can prevent WmiPrvSE.exe from saturating the machine:

  1. Find WmiPrvSE.exe in Process Lasso.
  2. Choose CPU Affinity → Always → Select CPU Affinity.
  3. Select one logical CPU.

On my 32-logical-processor system, this limits aggregate WmiPrvSE.exe usage to approximately 3.125%. A live five-second sample measured 3.17%, down from approximately 86%.

Use persistent CPU affinity—not CPU Sets—for a hard ceiling. The percentage represented by one logical CPU is 100 / logical processor count.

Caveat: This limits every WMI provider host, so other monitoring and system-management operations may become slower or time out. Remove the rule after Codex is fixed.

angelmoney · 1 day ago

Forensics from another affected machine + a collector-free workaround (VS Code extension)

Environment: Windows 11 Home 25H2 (build 26200), i7-14700K (28 threads), Norton 360, OpenAI.Codex 26.715.4045.0 (post-ChatGPT-merge shell, command-runner 0.145.0-alpha.18).

Symptoms (matching OP): within seconds of launching the desktop app, WmiPrvSE.exe climbs to ~38–50% of total CPU (40 threads, ~12 active) and the whole desktop starts stalling (multi-second UI freezes, intermittent black screens in GPU-accelerated apps). Alongside it we observed mass-spawned short-lived taskkill.exe processes — 143 concurrent at peak, plus 148 conhost.exe; total system process count 626 vs ~336 baseline.

WMI-Activity/Operational log evidence:

  • 934× event 5858 within ~2h, all from sequential short-lived client PIDs (exactly 4 errors each — a spawn-query-die pattern).
  • The failing operation is identical across those clients:

Start IWbemServices::ExecQuery - root\cimv2 : SELECT __PATH, ProcessId, CSName, Caption, SessionId, ThreadCount, WorkingSetSize, KernelModeTime, UserModeTime, ParentProcessId FROM Win32_Process
— i.e. the exact column set tasklist.exe/taskkill.exe request.

  • Result code 0x80041032 with "Throttling … hitting Max Memory quota" — under the storm WMI itself starts cancelling queries, which is what finally stalls every other WMI client on the box (Task Manager, AV, Explorer).
  • We also saw the repeated Win32_PerfFormattedData_PerfProc_Process enumerations described in the OP.

Local amplifier worth checking: ~/.codex/process_manager/chat_processes.json had accumulated 80 entries, most with "osPid": null (stale exec records from past agent sessions — vitest/pnpm runs). Entries with a null PID appear to force name-based lookups, i.e. fresh tasklist/taskkill spawns and the Win32_Process enumerations above. Clearing the file (with every Codex process stopped; it rebuilds empty) visibly reduces storm intensity but does not prevent it — the collector saturates WMI regardless (consistent with #29499's "idle after startup" reports). AV behavior monitoring amplifies further by scanning each of the hundreds of spawns per minute (Norton here; Defender coupling already documented in #30527).

Workaround that eliminated it entirely for us: run Codex through the VS Code extension instead of the desktop app. The extension launches the same engine as a bare app-server (codex.exe -c features.code_mode_host=true app-server) without the desktop shell around it. Measured with an active agent session running through the extension: WmiPrvSE 0.0% CPU, zero taskkill spawns, process count back to baseline — same sessions, none of the WMI load.

The Process Lasso affinity cap posted above also works as damage control (system stays responsive), but note it converts the CPU storm into a process backlog — the 143-concurrent taskkill.exe count above was measured while capped.

Implication for the fix: everything we measured points at the process collector living exclusively in the desktop shell (ChatGPT host), not in codex core / app-server — running the identical engine headless produces zero WMI traffic. Hopefully that narrows the search space.