Repository navigation
[Windows 10] DWM Composition handles accumulate after Codex tasks with tool calls #33192
Description
Summary
On Windows 10 22H2, I can reproduce persistent growth in DWM's Composition handle count after Codex tasks that make terminal tool calls. A no-tool task that replied only OK did not show the same growth. In one controlled five-call run, the Composition count increased by 22 and remained elevated throughout the 30-second period after the task finished.
After about four days of normal Codex use, DWM had 22,770 Composition handles, compared with 817 after a DWM restart. At that point, dragging an ordinary window could lag by 10 to 20 seconds. Restarting only DWM cleared the accumulated state and immediately restored smooth window movement.
In a separate control, every ChatGPT.exe and codex.exe process was absent for about 5 minutes 35 seconds. No comparable new growth was observed while Codex was closed, but the handles already held by DWM did not fall. So far, they have only been cleared by restarting DWM or Windows.
I cannot yet tell whether the lifetime problem begins in the Codex UI, Electron, Chromium, DirectComposition, DWM, or the graphics driver. This report documents the repeatable trigger and the resource signature.
Environment
- Windows 10 22H2, build
19045.7417, x64 - Codex MSIX
OpenAI.Codex_26.707.9981.0_x64 - Internal app version
26.707.72221, build5307 - Electron
42.1.0 - Chromium/ProductVersion
150.0.7871.115 - One internal display at
2400 x 1600, 60 Hz; no external display - Intel Iris Xe Graphics and NVIDIA GeForce RTX 3050 Ti Laptop GPU
- HAGS enabled (
HwSchMode=2) - Variable refresh optimization enabled (
VRROptimizeEnable=1) - MPO disabled (
OverlayTestMode=5)
I have seen the same general problem across several Codex desktop updates. The version above is the one used for the controlled captures below.
Reproduction
-
Start from a low DWM handle count after signing in to Windows or restarting DWM.
-
Open Codex and create a new task.
-
Ask it to make several separate, read-only terminal calls, for example:
Get-Date Get-Location Get-Process -Id $PID | Select-Object Id, ProcessName, HandleCount git status --short Get-ChildItem -Name | Select-Object -First 3
-
Record the count and type of DWM handles before the task, while it runs, and for at least 30 seconds after it finishes.
-
Repeat the task a few times. It is not necessary to keep Codex in the foreground.
-
For comparison, create a new task that only replies
OKand does not call any tools.
Expected: After a task finishes and its status UI settles, DWM Composition handles should return close to their previous baseline.
Actual: Tasks with several tool calls leave a small persistent net increase. Repeating these task cycles gradually builds a much larger DWM-side handle stock.
Controlled results
| Test | Workload | Persistent DWM handle change | Composition change |
|---|---|---|---|
| Plain text control | New task replied only OK; no tools |
+5 |
-1 |
| Five terminal calls | Five separate read-only calls | +10 |
+22 |
| Idle long task view | Visible and idle for about 10 minutes | +2 |
Not sampled by type |
| Idle short task view | Visible and idle for about 10 minutes | 0 |
Not sampled by type |
| Active task | Running for about 6 minutes | +66 |
Not sampled by type |
| Active task, Codex minimized | Running in the background | +55 |
Not sampled by type |
| Scheduled task | Natural unattended run | +88 |
Not sampled by type |
The two controlled runs used 30-second medians before and after the task. The DWM PID remained unchanged.
DirectComposition trace
I captured the five-call test with the Microsoft-Windows-DirectComposition and Dwm-Core ETW providers.
During the server-reported task interval, DirectComposition recorded four identical 12-resource creation batches for DWM channel 61. None of those 48 resources had a matching release before the trace ended. An identical fifth batch appeared about 2.1 seconds before the server startedAt timestamp, which may reflect local task initialization, but I cannot prove that from this trace.
Every batch had this resource type sequence:
201, 195, 195, 32, 32, 79, 87, 39, 58, 39, 58, 30
The resource handles were sequential and had openShared=false.
This capture did not include the Dwm-Core channel-attribution keywords, so I cannot map channel 61 to a specific client PID. The same batch signature also appeared occasionally outside the task interval. I therefore treat this as a correlation clue rather than proof that channel 61 belongs to Codex.
The capture used Dwm-Core keyword mask 0x21. A follow-up trace should use 0x900021 so that it also records PROCESS_ATTRIBUTION, CHANNEL_OPENED_FOR_PROCESS, CHANNEL_CLOSED_FOR_PROCESS, and COMMAND_PROCESSED_ONBEHALF. The DirectComposition mask can remain 0x5F.
DWM kept the same PID throughout the run. There was no lock-screen transition. Video.UI emitted no DirectComposition create or release events during the task interval, and the ShellExperienceHost burst began only after completion, consistent with the completion notification.
Related report
The closest existing report I found is #16374, which describes progressive Windows shell freezes associated with Codex. This may be part of the same broader problem. The additional evidence here is the DWM handle type, the no-tool control, and the DirectComposition capture.
Package note
The affected package is an Electron 42 and Chromium 150 application, not WebView2. I found task-status and sidebar lifecycle code in the packaged ASAR, but the production package has no source maps, so I could not map the observed resource lifetime to a specific source module.
Evidence retained locally
The most relevant sanitized results are included above. I have also kept the complete ETL, the two run summaries, before-and-after handle type diffs, and the extracted DirectComposition batches. I have not attached the raw ETL because it contains a wider process timeline.
Activity
codengine commentedon Jul 19, 2026
This issue also affects the CLI version of Codex, and it has been like this at least since 0.13*
codengine commentedon Jul 19, 2026
I let Codex analyze the issue and it figured out that it may relate to this commit:
6b3d82d
... which creates a private desktop per tool call and ignores the return value when it is closed. I am testing a custom build where a shared/reused private desktop is used and will report back
codengine commentedon Jul 19, 2026
Codex created this patch. I deployed the executables and ran thousands of tool calls. The memory and CPU consumption of dwm.exe did not move.
The main cause seems to be that every tool call creates a dedicated private desktop and it's closure is neither checked nor retried.
The attached patch, based on 0.144.5, creates one private desktop per Codex process.
codex-0.144.5-shared-private-desktop.patch
codengine commentedon Jul 20, 2026
10 hours later with 4 agents running in parallel - dwm still only reports 46 MB, load sub 0.1%, all windows are snappy... the main issue is really the desktop creation per tool call and the missing cleanup, or there is a leak in dwm.exe itself.
ManorianOTP commentedon Jul 30, 2026
Adding another Windows reproduction on a current desktop build.
Environment
26.721.4979.026200.8875(25H2)Symptom
This is system-wide compositor/input lag, not only a slow Codex window:
Resource headroom
A live read-only snapshot during the affected session showed approximately:
taskkill.exeorconhost.exeprocessesThis therefore did not coincide with conventional CPU or physical-memory exhaustion.
The symptom is materially similar to the delayed ordinary-window dragging reported in this issue. It may also overlap with long-thread renderer/event-state growth discussed in #21134, but the important distinction here is that the rest of Windows becomes nearly unusable too.
Expected behavior
Long-running local Codex workflows should not degrade Windows DWM/compositor or system-wide input responsiveness when the machine retains substantial CPU and RAM headroom. DirectComposition/DWM and renderer resources should remain bounded and be released during prolonged background work.
Private prompts, project names, session identifiers, filesystem paths, and raw logs are intentionally omitted. Privacy-safe diagnostics can be collected through the official feedback channel if maintainers specify what additional counters or trace profile would be useful.
josh-robey commentedon Aug 8, 2026
Confirming this is still unfixed in the current Store build, with a concrete Windows 10 reproduction.
Environment
OpenAI.Codex_26.803.5235.0_x64__2p2nqsd0c76g0(current as of Aug 6)app\resources\codex.exestill importsCreateDesktopW/CloseDesktop, and the sandbox helper (codex-command-runner.exe) still accepts--windows-sandbox-private-desktopand is re-copied into%USERPROFILE%\.codex\.sandbox-bin\on every launch.Observed behavior
dwm.execlears the handles and immediately restores responsiveness. Nothing else does - not a GPU driver reset, not killing the renderer tree.Timeline impact
This has been slowing my PC down for literally 6-7 months. I have been trying to figure out what has been happening the whole time, and it has been progressively getting worse. This needs to be fixed ASAP please - it is killing my PC.
What would help
CreateDesktopWper command, close result ignored, no retry. The shared-private-desktop patch in this thread (one desktop per process) is a validated direction - thousands of tool calls with zero DWM growth, 10h/4-agent run with DWM at 46 MB.CloseDesktop, or expose a supported toggle that stops per-call desktop creation without losing the sandbox isolation. Note that the existingwindows.sandbox_private_desktop = falseescape hatch does not preserve the isolation - it disables it entirely.Happy to provide a WPR/ETW trace or Process Monitor capture on request. This has been open since July 14 and is still affecting current builds - it's the difference between Codex being usable and not on Windows 10.
deathy commentedon Aug 10, 2026
Adding DWM-side object counts that quantify this per tool call, plus where the CPU actually goes.
Environment
26200(25H2), x64, 24 logical cores, 64 GiB RAMOpenAI.Codex_26.803.5235.0_x64__2p2nqsd0c76g032.0.16.1088Method
Rather than counting kernel handles, I dumped
dwm.exe(full memory,MiniDumpWriteDump)and counted live composition objects by scanning for their vtable addresses:
Tool-call counts come from
~/.codex/.sandbox/sandbox.<date>.log, countingsetup refresh: spawning ...codex-windows-sandbox-setup.exeoccurrences inside eachmeasurement window.
Both measurements below were taken against the same
dwm.exeinstance (PID unchanged),with Codex fully exited before the closing measurement in each case. No other
application was started, closed, or resized during either window.
Results: the leak is a constant per tool call
CVisualdeltaCDesktopTreeDatadeltaCVisualOcclusionInfodeltaCVisualper tool callCDesktopTreeDataper tool callThe per-tool-call figure reproduces to within 0.3% across two runs whose durations
differ by 5x. The leak tracks tool-call count, not session length or wall-clock time.
CVisualandCDesktopTreeDatastay locked at 1:1 throughout.None of it is released when Codex exits. Both closing measurements were taken with no
ChatGPT.exe/codex.exeprocess running; the counts above are what remained.For scale, immediately after a
dwm.exerestart this machine sits at 4,752CVisual.Two Codex sessions took it to 9,487 - roughly doubling the entire desktop's composition
tree from ~750 tool calls.
Where the CPU goes
Sampled profile of
dwm.exe(xperf -on PROC_THREAD+LOADER+PROFILE -stackwalk profile,symbols from the public server) once the tree had grown large, showing why this presents
as system-wide lag rather than a Codex-only problem:
DWM walks the visual tree three times per frame plus a transform pre-walk, all O(visual
count). Under 8% of its time is spent actually drawing or presenting - the rest is
bookkeeping over the accumulated tree. On this machine that reached ~90% of one CPU core
with the compositor otherwise idle, and restarting
dwm.exereturned it to ~7%.Happy to re-run with additional counters if that would be useful.
TobyIsADog commentedon Aug 13, 2026
Confirming that this is still happening on a newer Windows Store build.
Environment
26.803.10989.0(app-server0.147.0-alpha.6.6)2620032.0.101.6881and NVIDIA RTX 4060 Laptop GPUWhat happens
After Codex has been running tool-heavy tasks for many hours, the mouse pointer starts moving in visible steps across the desktop and other applications. The rest of Windows remains responsive. Signing out of Windows or rebooting restores smooth pointer movement, but the problem returns after another long Codex session.
During one affected session, Codex and Windows had been running for about 28 hours. The sandbox log contained 9,688 launches of
codex-windows-sandbox-setup.exe. At that point:dwm.exewas using 749–766 MiB of private memory and had about 994 MiB of GPU memory committed.This does not look like ordinary CPU or memory pressure, and it matches the DWM accumulation described in this issue.
Why the private-desktop cleanup still looks relevant
The current code still creates a fresh randomized
CodexSandboxDesktop-*for a sandboxed process:LaunchDesktop::prepare(...).PrivateDesktop::createcallsCreateDesktopW.CloseDesktop.Together with the repeatable per-tool-call
CVisualandCDesktopTreeDatagrowth reported above, this points to the same failure mode: private desktops are created repeatedly, some composition state is not released, and DWM gradually has more work to do each frame.A fix should keep the number of private desktops bounded or verify that desktop cleanup actually succeeds and that the related DWM objects return to baseline.
roymasad commentedon Aug 13, 2026
Same issue with win UI lag happening with me also with Codex left running for half a day.
A force kill of dwm.exe is needed to restart it and get the UI back to a normal state.
smallwangcf commentedon Aug 14, 2026
Title: Windows-wide mouse/input stutter persists after opening a second Codex window until all ChatGPT.exe processes are terminated
I am seeing intermittent system-wide mouse/input stutter on Windows while using Codex in the ChatGPT Desktop app. Chrome, File Explorer, and Codex are all affected. An unusual observation is that putting Task Manager in the foreground makes mouse movement feel smooth across the desktop, even when the Task Manager window is small.
The clearest reproduction I have observed is:
ChatGPT.exeprocesses in Task Manager. The system immediately becomes smooth.This does not appear to be reliably caused by running two tasks or by web preview itself. Opening the second window appears to trigger or expose a background app-process state that remains after the UI windows are closed.
Read-only snapshots during the lag did not show general resource saturation: CPU was about 15% average (20% peak), DPC about 0.11% average, and interrupts about 0.63% average. The ChatGPT group had about 13 processes and about 3.19 GB private memory. A ChatGPT GPU process used about 10% average / 24% peak 3D, while
dwm.exeused about 2.7% average / 3.9% peak. I saw no display-driver reset, DWM, or WHEA error around the second-window reproduction time.Hardware: 32 GB RAM, NVIDIA RTX 4060 + Intel UHD 770, 60 Hz display. Windows reports build 26200.8875. I also saw one earlier WER
RADAR_PRE_LEAK_64event forChatGPT.exe, but I cannot prove that it is related.Could you please investigate whether the Windows desktop app can leave an Electron/Chromium renderer, GPU-process, DirectComposition, or DWM-composition state active after opening a second window or running Codex tools? This is a hypothesis based on the observed behavior, not a confirmed root cause.
I can provide a sanitized diagnostic summary. I have not captured an ETW trace yet because Windows Performance Recorder requires an elevated administrator session.
SayrWolfridge commentedon Aug 15, 2026
Additional sanitized evidence for #33192
No raw ETL, CSV export, screenshot, process tree, command line, or machine-specific path is attached. All times below are relative to the retained trace interval.
Reproduction on a newer build
26.810.4967.0codex-command-runner-0.148.0-alpha.9.exeCompositionchange:+18, exactly+2per runner invocationThis reproduces the issue on a newer package than the one in the original report.
ETW handle-lifetime evidence
A separate retained ETW slice from package
26.803.10989.0and command runner0.147.0-alpha.6.6contained:Compositioncreation burstsWindowUpdateevents within 50 msWindowUpdateevents fell inside those matched burst windowsThe observed enrichment of runner
WindowUpdateevents around DWM creation bursts was approximately 80x over a uniform-background expectation at a 50 ms window.Symbolized creation path
The repeated DWM-side creation path was:
Interpretation
The evidence points to per-command Windows sandbox runner lifecycle as the trigger. Each short-lived runner produces a Win32k window update that is followed within milliseconds by DWM desktop/global-light-set creation, with two Composition objects remaining outstanding after the runner exits.
The trace does not establish whether the missing release belongs in the runner, console/window lifecycle, DirectComposition interop, or DWM itself. It does narrow the trigger from the general Codex UI to the per-command Windows runner path.
GaleVale commentedon Aug 23, 2026
Adding sanitized evidence from the current Store package. This confirms that the system-wide DWM bottleneck is still present on a build newer than the ones above, while also showing that a short total-handle test does not reproduce the lifetime signature every time.
Environment
OpenAI.Codex_26.818.5229.0_x64151.0.7922.17026200, 24 logical processors, 96 GiB RAM32.0.16.1088HwSchMode=2); noOverlayTestModeMPO overrideThe symptom is Windows-wide window-drag/input stutter, not merely a slow Codex window. It persisted with substantial CPU/RAM headroom and low GPU, disk, DPC, and interrupt activity. It also reproduced at 144 Hz after the emulator device process had exited, so the emulator is not a necessary condition.
WPR/ETW evidence on
26.818.5229.0I captured the affected drag interval with the Microsoft
CPU.Verbose + DesktopComposition.LightWPR profiles, then decoded it with WPA/Xperf. The analysis interval was restricted to the actual 21.5-second drag action (0.5-22.0 s), excluding trace-save work.85.93%of total CPU capacity as Idle.dwm.exeaveraged0.99logical core.85.50%of DWM sampled CPU;87.10%of that thread's exclusive samples were indwmcore.dll.8.73 us; sustained scheduler starvation was not present.1.96% / 0.57%of that DWM frame thread. GPU work was not saturated, and no third-party display/overlay module appeared in the hot path.ChatGPT.exeprocesses together averaged about0.56logical core; no single Codex process saturated a core.An earlier lossless
DesktopComposition.Lightcapture over an 18.482-second DWM root region showed:ProcessFrame:14.097 sPresent:7.477 sOcclusion:4.169 sPreCompute:2.935 sVSyncDPC:142.35/s, matching the 143.85 Hz display modeThis independently matches the DWM-side CPU shape reported above: the user-visible failure is a serial composition/frame-thread bottleneck while the rest of the machine remains mostly idle.
Mitigation A/B
Disabling “Show window contents while dragging” at 144 Hz reduced:
169.67% -> 76.93%on a one-core-equals-100% scale (-54.7%)45.21% -> 16.35%(-63.8%)190,638/s -> 43,261/s(-77.3%)This is a useful workaround, not a fix: DWM still remained around
0.77core, and the user must give up live window contents. Reducing the display to 60 Hz also improves usability but does not eliminate the DWM bottleneck.Short handle control on the current build
I also ran two controlled five-terminal-call batches while sampling DWM's total handle count:
2392 -> 2391(range2391-2394)+45versus baseline), followed by recovery toward23952424to2395and remained there through the end811 / 674 MiBduring this short testThis test did not enumerate the
Compositionhandle type, so it does not disprove the typed per-runner leak documented in the comments above. It does show that the short-run total-handle signature is state-dependent on26.818.5229.0, while the DWM frame-thread performance failure remains reproducible.Request
Please keep investigating this against the current Windows desktop package rather than treating it as limited to the older builds. I retained the original 1.71 GiB CPU+composition ETL and sanitized WPA/Xperf exports locally. I have not attached the raw ETL because it contains a wider process timeline. If maintainers provide a privacy-safe upload route and specify the desired provider/keyword set, I can supply the trace or repeat a targeted capture.
MangelSpec commentedon Aug 27, 2026
How is this issue not considered a very high priority yet? I installed the app for the first time and genuinely thought something was wrong with my PC because the entire Windows desktop became increasingly unusable after only a few hours, even when closing every software (including GPT).
After finding this thread, I’m pretty shocked to see reports going back this far without any visible indication that the issue has been elevated.
In my case, restarting dwm.exe immediately fixes the system-wide lag, while Codex can remain open. CPU, GPU and memory usage are all low. The apparent handle/composition-resource leak also means the problem is accumulating long before the desktop becomes noticeably unusable.
I also asked several friends who use the Windows app, and every single one of them confirmed experiencing the same degradation.
This makes the Windows app effectively unusable for me and seriously makes me consider uninstalling it again. Is this being actively investigated / treated as a high-priority issue?
chess-oai commentedon Aug 28, 2026
ChatGPT v26.825.32147 includes a fix for one cause of Windows stuttering and slowdowns during long sessions. Sandboxed commands could cause Desktop Window Manager (
dwm.exe) resources to accumulate. The fix reuses private Windows desktops for commands with the same permissions.Please update to ChatGPT v26.825.32147 or later, restart the app, and let us know whether this helps.
If the problem continues after updating, please share your version and steps to reproduce.
Thank you for your reports and investigation!
Hajmer777 commentedon Aug 29, 2026
[Windows 10][Codex 26.825.4187.0] DWM handles grow to ~28K and cause severe system-wide window-drag lag
Codex version
Microsoft Store/MSIX package: OpenAI.Codex 26.825.4187.0
Embedded Chromium: 151.0.7922.174
System
Problem
After extended Codex Desktop usage, dragging any Windows application becomes extremely delayed. The dragged window can lag many seconds behind the mouse pointer, while the rest of the system remains fast.
Closing Codex or restarting Explorer does not repair the already degraded desktop compositor.
Measurements while affected
The current Codex profile also recorded 86 occurrences of:
[desktop-notifications][global-error] ResizeObserver loop completed with undelivered notificationswithin approximately three minutes.
Recovery test
I force-restarted only dwm.exe as SYSTEM.
Before:
After:
Window dragging became immediately smooth again without restarting Windows.
Codex itself did not recover from the DWM restart and had to be terminated through Task Manager and relaunched.
Reproduction pattern
Expected behavior
Codex tasks, renderer updates, notifications, tool calls, and process cleanup must release their DirectComposition/DWM resources. Long Codex sessions should not progressively degrade the Windows desktop compositor.
Related issues
This is still reproducible on Codex 26.825.4187.0.
codengine commentedon Aug 30, 2026
Thanks for working on this. I tested and inspected the fix from #40672, including its integration into 0.151.0. It fixes an important part of the problem, but not the complete failure mode I observed.
The PR fixes private-desktop lifetime and reuse: the parent retains desktops and reuses them only when the sandbox account and effective policy match. That removes repeated private-desktop creation and is the right behavior, especially for TTY/ConPTY commands.
However, those desktops still live under the interactive
Winsta0window station. In 0.151.0:codex-command-runneris still a console-subsystem executable;ConsoleMode::Inherit—only the filesystem helper usesNoWindow;Winsta0.The traces indicate that desktop lifetime alone was not the root issue. The remaining trigger was the repeated creation of console/window composition resources inside the interactive window station. DWM retained DirectComposition resources after the short-lived command process tree exited. Over a long session, DWM memory/handles and frame-thread work accumulated until dragging windows and system-wide input became sluggish.
In a controlled ETW test, 12 command executions with the shared/reused
Winsta0desktop approach produced 144 DirectComposition resource-creation events and no corresponding releases. Therefore, pooling the desktop reduced churn but did not remove DWM from the command lifecycle.The fix that has remained stable for me does the following:
codex-command-runneras a Windows GUI-subsystem executable.CREATE_NO_WINDOWfor non-TTY commands and setup helpers.Winsta0.station\desktopthroughSTARTUPINFO.lpDesktopand keeps both handles alive for the child lifetime.Winsta0desktop for TTY/ConPTY commands.STARTF_FORCEOFFFEEDBACKfor the runner to avoid the unrelated busy-cursor feedback on every command.With that topology, the same ETW control produced zero of the problematic DirectComposition creation events, with zero lost ETW events. After approximately one week of normal use, DWM memory has remained low and I have seen no recurrence of the drag/input lag.
So my conclusion is:
Winsta0, not pooling those command desktops.The 0.151.0-based implementation I am currently using is here:
https://github.com/codengine/codex/tree/local/fix-dwm-degredation
The noninteractive station implementation is here:
https://github.com/codengine/codex/blob/local/fix-dwm-degredation/codex-rs/windows-sandbox-rs/src/desktop/noninteractive.rs
Would you consider routing elevated non-TTY commands through a noninteractive window station upstream while retaining the new pooled desktop path for TTY commands? I can also repeat a targeted ETW capture or provide more detailed event data if useful.
TheThane69 commentedon Aug 30, 2026
I packaged a guarded workaround for this recovery path:
https://github.com/TheThane69/ChatGPT-DWM-Memory-Leak-Workaround
It validates the active session and exact dwm.exe identity, records DWM/display
state, recreates only the affected DWM process, reloads the relevant Windows
display components, and verifies the final display state.
Observed result on the original affected session:
It is an unofficial workaround, not a root-cause fix, and its physical-console
path currently has intentionally strict compatibility checks.
acumina commentedon Aug 31, 2026
Adding another Windows 11 reproduction and a successful workaround A/B.
Original affected build
OpenAI.Codex_26.820.10647.0_x64Symptoms
After several days of tool-heavy Codex use, the whole Windows desktop became increasingly sluggish. Dragging Windows Settings was worst, Codex was intermediate, and classic Control Panel was least affected. At 60 Hz the visible stutter was reduced, but windows followed the pointer with a long delay. At 240 Hz the stutter was more obvious.
Fully exiting ChatGPT/Codex did not restore responsiveness. Restarting Explorer, resetting the graphics driver, changing refresh rate, disabling transparency, using one window, disconnecting the mouse, and lowering mouse polling rate did not fix it. Signing out of Windows and signing back in immediately restored normal behavior at both 60 Hz and 240 Hz.
During the affected session:
502.6 MB437.6 MB1386 MiBImmediately after signing back in:
218.1 MB105.5 MB720 MiBTwo lossless ~21-second GPU/DWM traces also showed a notable change in
AllocationFault Reason 1: approximately31.7/sand46.8%of allocation faults in the bad state, versus11.1/sand8.9%after signing back in.Workaround tested
Changing only
windows.sandbox = "elevated"to"unelevated"did not avoid the private-desktop path. I then backed up~/.codex/config.tomland used:After restarting the app, a Win32 desktop probe confirmed that new tool processes changed from a randomized
CodexSandboxDesktop-*desktop toDefault.The workaround removes private-desktop UI isolation, but retains the native file/permission sandbox. It is therefore a compatibility workaround rather than an ideal security-preserving fix.
Result after about three days
The system-wide dragging/input lag has not returned. At 240 Hz, Windows Settings and Codex remain responsive.
A controlled run of 20 separate minimal terminal calls produced no immediate DWM growth:
420.6 MBprivate,2141handles,121.5 MBworking set420.7 MBprivate,2137handles,121.5 MBworking setThere were no new relevant Application or System events, and all ChatGPT/Codex processes remained responsive.
The app subsequently auto-updated to MSIX
26.825.5331.0, so I cannot cleanly separate the effect ofsandbox_private_desktop = falsefrom newer changes such as #40672. However, disabling the per-command private-desktop path has been effective so far, and the previously observed per-tool-call resource increase did not reproduce.No raw ETL, account data, local paths, API credentials, or complete logs are included.
TobyIsADog commentedon Sep 5, 2026
@chess-oai Cursor stutter persists on Codex app 26.901.5280.0 (
codex-cli 0.153.4) despite #40672.On my machine, cursor delay and stutter consistently build up whenever Codex runs for extended periods. It starts with noticeable lag during fast pointer movement and progresses until the pointer is almost unusable across Windows. Restarting Codex does not clear the accumulated stutter, even while the rest of the system remains responsive.
Local ETW analysis identifies DWM input hit-testing blocked on composition-tree locks. During continuous pointer movement, all 508
ProcessQueuedMouseEventscalls lasting at least 8 ms contained these waits, accounting for 98.78% of their combined duration:CInputManager::s_HitTestRequest → CTreeLock::AcquireShared, with the composition thread readying the input thread inCComposition::PreRender.CInputManager::s_HitTestRequest → CComposition::GetDesktopTree, with the composition thread readying the input thread inCComposition::CleanTrees.The longest call was 13.275 ms. A previous capture during more severe stuttering showed the same pattern in all 211 calls lasting at least 16 ms, reaching 25.51 ms. The immediate input delay is dominated by these lock waits.
A desktop-reuse gap remains in
rust-v0.153.4: each sandboxed filesystem request spawns a new child through the Windows sandbox wrapper. The desktop cache is process-local, and the wrapper exits after each request, preventing reuse across requests.In four otherwise identical read-only FS requests, both private-desktop ON runs created a new Codex desktop and the same 12-resource DirectComposition cluster; both OFF runs created neither. This establishes repeated resource creation on the helper path. Whether those resources persist and cause the later lock contention remains unresolved.
Please check whether private desktops can be reused across FS-helper processes, and whether their repeated creation contributes to DWM composition-tree lock contention.
Cielluloid commentedon Sep 9, 2026
Building on TobyIsADog’s FS-helper analysis, I’m adding evidence that DWM table entries remain after the kernel Desktop objects have been deleted.
These measurements were captured on September 9, 2026 (UTC+08:00), on Windows 10 x64, build family 19045, with a Codex backend/command runner 0.153.4. The tested path used the elevated Windows sandbox with private desktops enabled.
File-operation A/B
A passive ETW trace recorded process lifetimes and Desktop ObjectCreate/ObjectDelete events. On disposable text files, the observed sequence was:
All 10 creators belonged to this process chain:
All 10 kernel Desktop objects were subsequently deleted. Lifecycles were counted using create/delete intervals, accounting for reused kernel addresses. The 3/4/3 counts describe this capture, not a fixed number for every patch.
Across the same DWM process lifetime, its desktop/GlobalLight table grew from 13,343 to 13,353, with all previous entries preserved. Earlier controlled empty-Desktop lifecycle tests independently produced one retained table entry per cycle.
This establishes completed kernel Desktop lifecycles alongside persistent DWM table growth. It does not provide a one-to-one mapping between every ETW object and every DWM desktop ID.
Composition identity comparison found 24 added, 2 removed, net +22. The additional net 2 beyond the earlier two-per-Desktop pattern remain unassigned.
Performance and recovery
On this machine, 98.45% of samples on the saturated DWM scene-update thread were in
CWindowList::UpdateScene. Local code/object inspection connected its traversal to the desktop/GlobalLight table and coordinate-visual reference counting. This is a measured drag bottleneck; it does not establish the cause of the hit-testing lock waits reported on another machine.One separately authorized DWM replacement reduced:
Window dragging became smooth. The Codex UI subsequently hung and required relaunch; Application Hang events corroborated that side effect. DWM replacement resets other state too and does not validate a permanent client fix.
chess-oai commentedon Sep 18, 2026
we’ve shipped a follow-up fix in ChatGPT 26.915.31945 (Microsoft Store package 26.915.4065.0) that addresses the filesystem-helper behavior identified in this thread. helpers now reuse a desktop retained by the longer-running process instead of creating a fresh one for each operation.
KubaO commentedon Oct 16, 2026
Lol, I wish I found this one earlier. I've just had to diagnose the same issue, except it was my own test runner (nothing to do with Codex) that was creating private desktops, thousands of them. Same symptoms, same cause: DWM leaks handles - not desktop handles, but compositor handles that it creates when a desktop is created.