Windows app stutters when switching chats or opening Settings

Open 💬 8 comments Opened Jun 28, 2026 by kangmingxuan
💡 Likely answer: A maintainer (github-actions[bot], contributor) responded on this thread — see the highlighted reply below.

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

Windows app package: OpenAI.Codex 26.623.5546.0

PATH Codex CLI/runtime after update: codex-cli 0.142.3

The running app-server during capture was the embedded Windows app binary:

C:\Program Files\WindowsApps\OpenAI.Codex_26.623.5546.0_x64__2p2nqsd0c76g0\app\resources\codex.exe app-server --analytics-default-enabled

Note: Directly executing the embedded WindowsApps app\resources\codex.exe --version returned Access Denied, so I can confirm the Windows app package version and PATH CLI version, but not a separate embedded app-server version string.

What subscription do you have?

Not provided in this public report. I can update this if needed.

What platform is your computer?

OS: Windows 11 Pro
OS version: 10.0.26200
OS build: 26200
Architecture: x64
Logical processors: 32
Memory: 63.77 GB
Shell: PowerShell

What issue are you seeing?

The Codex Windows desktop app visibly stutters when switching conversations or entering Settings. During the stutter, mouse movement also feels interrupted.

I captured a clean WPR/ETW trace using these profiles:

GPU
DesktopComposition
HTMLResponsiveness

The capture was launched from an external elevated PowerShell process to reduce observer effect from Codex itself.

WPA export shows a large UI responsiveness delay:

Table: repro_UI_Delays_Summary_Table_Delays_By_Process,_Type.csv
Process: Codex.exe <OpenAI.Codex> (8308)
UI delay duration: 37.965 s
Start time: 0.392 s
End time: 53.326 s

This happened while the machine was not under overall CPU pressure:

WPA CPU precise Idle: 88.55%
WPA CPU sampled Idle: 89.44%
Codex.exe <OpenAI.Codex> (8308): 2.05% CPU in WPA precise table
codex.exe <OpenAI.Codex> (12748) app-server: 0.86% CPU in WPA precise table
Codex.exe <OpenAI.Codex> (6476) renderer: 0.71% CPU in WPA precise table

The same trace shows heavy repeated child-process activity from the Codex app-server. Using command-line detail rows from WPA Processes Lifetime to avoid double-counting aggregate PID rows:

| Executable | Detail rows | Total table duration | Max table duration |
| --- | ---: | ---: | ---: |
| git.exe | 494 | 161.320 s | 2.250 s |
| conhost.exe | 88 | 75.250 s | 4.000 s |
| powershell.exe | 60 | 74.810 s | 4.030 s |
| node_repl.exe | 36 | 575.450 s | 39.400 s |
| node.exe | 28 | 1.220 s | 0.050 s |
| taskkill.exe | 28 | 5.060 s | 0.250 s |

Repeated Git command patterns:

| Command pattern | Count |
| --- | ---: |
| "git" -c core.hooksPath=NUL -c core.fsmonitor=false remote -v | 62 |
| git.exe -c core.hooksPath=NUL -c core.fsmonitor=false remote -v | 62 |
| "git" -c core.hooksPath=NUL -c core.fsmonitor=false rev-parse HEAD | 61 |
| git.exe -c core.hooksPath=NUL -c core.fsmonitor=false rev-parse HEAD | 61 |
| "git" config --null --get core.fsmonitor | 61 |
| git.exe config --null --get core.fsmonitor | 61 |
| "git" -c core.hooksPath=NUL -c core.fsmonitor=false status --porcelain | 60 |
| git.exe -c core.hooksPath=NUL -c core.fsmonitor=false status --porcelain | 60 |

Git detail rows occurred from 1.748 s through 72.101 s, about 421 detailed Git command rows per minute.

Node/runtime churn in the same capture:

node_repl.exe: 36 lifecycle rows, parent process is Codex app-server codex.exe (12748)
node.exe --version: 28 rows
taskkill.exe /PID ... /T /F: 28 rows, apparently cleaning up node_repl PIDs

500 ms process sampling cross-check:

Main app Codex.exe (8308):
  max CPU about 108% of one core
  average CPU about 55% of one core
  max working set 1723 MB
  max private memory 2169 MB

App-server codex.exe (12748):
  max CPU about 82% of one core
  average CPU about 23% of one core
  max working set 384 MB

Renderer Codex.exe (6476):
  max CPU about 78% of one core
  average CPU about 22% of one core
  max working set 806 MB

No sampled Responding=False was observed, but ETW HTML responsiveness reports the UI delay above.

codex doctor --summary --ascii --no-color after updating the PATH runtime:

Codex Doctor v0.142.3 - windows-x86_64
16 ok | 1 idle | 2 notes | 1 warn | 0 fail degraded

Relevant checks:
- Runtime: standalone 0.142.3-x86_64-pc-windows-msvc
- Config loaded
- Auth configured
- State DB healthy
- Network websocket connected
- Active provider endpoints reachable
- Warning: rollout files are missing from the state DB

This does not look like system-wide CPU/GPU exhaustion. It looks like the Codex Windows app/UI path is experiencing long HTML responsiveness delay while app-server background work repeatedly polls Git state and starts/stops Node runtime helpers.

What steps can reproduce the bug?

  1. Launch the Codex Windows app.
  2. Keep an existing workspace/thread open.
  3. Start WPR with GPU, DesktopComposition, and HTMLResponsiveness.
  4. Switch between conversations and open the Settings UI.
  5. Observe visible UI stutter and mouse cursor stutter.
  6. Stop WPR and export with Windows Performance Analyzer / WPAExporter using HtmlResponsivenessAnalysis.wpaprofile.

What is the expected behavior?

Switching conversations and opening Settings should be responsive, without visible UI freezes or cursor stutter.

Background Git scanning and Node/MCP/runtime helper management should not create enough churn to coincide with large UI responsiveness delays.

Additional information

Related issues I found while checking for duplicates:

  • #30185: generic Windows app performance lag/stutter report.
  • #29911: Windows Git scanner repeatedly launching Git for empty .git directories.
  • #25744: macOS helper/node_repl accumulation and input lag.
  • #29822: Windows CLI /new and resume slow after 0.142.0, possibly app/runtime related but not the same reproduction.

I have retained the raw WPR trace locally:

codex-ui-repro-20260628-165114.etl
Size: 3,292,528,640 bytes

I am not attaching the raw ETL publicly because it is large and may contain sensitive local activity. I can provide it through an appropriate private channel if useful.

A smaller evidence package is available locally and contains:

environment.txt
codex-doctor.txt
status.txt
wpr-output.txt
selected WPA exported CSV files
processes-before-codex-family.csv
process-samples-codex-family.csv
processes-after-codex-family.csv
process-lifetime-codex-family.csv
codex-ui-performance-summary.md

View original on GitHub ↗

8 Comments

github-actions[bot] contributor · 2 months ago

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

  • #29821
  • #29408
  • #30345
  • #29110

Powered by Codex Action

kangmingxuan · 2 months ago

Additional source-code correlation and proposed fix

I did another pass comparing the WPR traces with the public source at bdd282f3bbd55df3a869a5438519cd948c134d4d.

The highest-confidence hypothesis is that latency-sensitive desktop UI paths are hitting local thread listing / metadata repair / Git enrichment work, rather than a general CPU saturation issue.

Relevant source paths:

  • ThreadListParams.useStateDbOnly defaults to false, and the protocol comment says false preserves JSONL rollout scan-and-repair behavior:

https://github.com/openai/codex/blob/bdd282f3bbd55df3a869a5438519cd948c134d4d/codex-rs/app-server-protocol/src/protocol/v2/thread.rs#L1099-L1103

  • thread/list passes useStateDbOnly through to the thread store:

https://github.com/openai/codex/blob/bdd282f3bbd55df3a869a5438519cd948c134d4d/codex-rs/app-server/src/request_processors/thread_processor.rs#L1907-L1966

  • The local thread store uses the state DB fast path only when use_state_db_only is true; otherwise it falls back to rollout scanning:

https://github.com/openai/codex/blob/bdd282f3bbd55df3a869a5438519cd948c134d4d/codex-rs/thread-store/src/local/list_threads.rs#L151-L209

  • The Git metadata path runs short-lived Git commands such as status --porcelain, remote -v, and rev-parse HEAD:

https://github.com/openai/codex/blob/bdd282f3bbd55df3a869a5438519cd948c134d4d/codex-rs/git-utils/src/info.rs#L291-L300
https://github.com/openai/codex/blob/bdd282f3bbd55df3a869a5438519cd948c134d4d/codex-rs/core/src/turn_metadata.rs#L315-L320

  • core.fsmonitor is intentionally probed every time:

https://github.com/openai/codex/blob/bdd282f3bbd55df3a869a5438519cd948c134d4d/codex-rs/git-utils/src/fsmonitor.rs#L42-L59

This matches the WPR traces: Codex.exe shows long UI delays while system CPU remains mostly idle, and the trace contains many short-lived git.exe processes with status --porcelain, remote -v, rev-parse HEAD, and config --null --get core.fsmonitor.

Proposed fix:

For latency-sensitive Windows desktop UI paths such as chat switching, sidebar history refresh, and entering Settings, call thread/list with useStateDbOnly: true. Move JSONL rollout metadata repair and Git enrichment to a background, batched, or idle-time path, then refresh the UI when repaired metadata is available.

A second useful optimization would be to cache or dedupe Git metadata probes per repo root for a short TTL, especially git status --porcelain and the repeated core.fsmonitor probe.

This may be Windows-amplified rather than Windows-only: the same app-server paths are cross-platform, but Git-for-Windows process startup, NTFS metadata access, Defender scanning, and the Windows desktop shell make repeated short-lived Git probes more visible as UI stalls.

areslp · 1 month ago

Follow-up from the current Windows release with a source-level correlation.

Current build

  • Microsoft Store package: OpenAI.Codex_26.715.4045.0_x64__2p2nqsd0c76g0
  • Desktop release: 26.715.31925
  • Bundled app-server: 0.145.0-alpha.18
  • Windows 11 x64

The update made the recurring system-wide stutter substantially worse. The Corsair K70 is still in BIOS mode, reducing the observed composite USB/HID nodes from 8 to 2, but that workaround is no longer enough.

Git process evidence

A narrow watchdog observed Codex-owned Git processes from 19:27:58 through 21:06:55 and terminated only processes older than 3 seconds. It recorded 623 process rows (including the Git-for-Windows wrapper and real child process as separate rows):

  • 241 × rev-parse HEAD
  • 237 × remote -v
  • 81 × status --porcelain
  • additional rev-parse --git-dir / fsmonitor probes

Immediately after the 4045 package started, the 20:55–20:59 window alone produced 56 such >3-second rows in minute-like bursts.

Running the same Git commands manually in the same repository took only 32–46 ms, so this is not an intrinsically slow repository or Git installation.

No new WER AppHangTransient or Application Hang event 1002 was recorded during these short recurring stalls. That means formal Windows hang telemetry misses this failure mode even while the app and mouse visibly stutter.

Public source correlation

The bundled Rust app-server path collects rev-parse HEAD, remote -v, and status --porcelain together for turn workspace metadata. Its five-second timeout currently uses Tokio kill_on_drop(true), which terminates only the directly spawned wrapper.

Open PR #30235 documents the exact residual-child mechanism: if git resolves to a wrapper, the wrapped Git process can keep scanning after the timeout. However, that PR only adds Unix process-group cleanup; the Windows path still has no equivalent process-tree termination.

A Windows-specific fix should retain the child until timeout, run hidden taskkill /PID <pid> /T /F, and reap the wrapper/output future. The existing exec-server already uses taskkill /T /F for Windows stdio process trees, so this would follow an established repository pattern rather than introduce a new platform mechanism.

I have a focused patch and regression test locally; local codex-git-utils tests pass (27/27), and the Windows-only Tokio code cross-checks successfully.

areslp · 1 month ago

Follow-up: I now have a focused implementation available at https://github.com/areslp/codex/commit/b8d7f3c58da35b48d96bf6fb1ed5ed721c2a4fa8

It adds Windows-specific timeout cleanup for the entire wrapped process tree for all Git metadata probes, plus a regression test that verifies a wrapped child cannot survive the timeout.

Validation completed:

  • just test -p codex-git-utils: 27/27 passed
  • just fix -p codex-git-utils
  • just fmt
  • Windows target compile check passed
  • Native win-l taskkill /T /F semantics test confirmed parent and child processes were gone and the delayed marker was never written

The repository contribution guide says external PRs are by invitation only, so I have not opened an unsolicited PR. If maintainers agree with this approach, please invite me to submit it and I can open the PR immediately.

areslp · 1 month ago

Follow-up after updating the same Windows installation to the July 20 Store package.

Current build and HID control

  • Microsoft Store package: OpenAI.Codex_26.715.7063.0_x64__2p2nqsd0c76g0
  • Windows 11 x64
  • Corsair K70 restored to normal composite mode: 8 present USB/HID nodes
  • concurrent_reasoning_summaries = false remains configured

The HID/main-thread regression appears improved in this build. During a 45.78-second read-only external sample, the main window was responsive in 131/131 checks, with zero Responding=False samples and no new Application Hang event 1002. This is only a short smoke result, but it matches the positive 7063/52143 reports in #33780/#33884.

Git process storm still reproduces

The same sample did not execute Git itself, but observed:

  • 33 distinct git.exe PIDs
  • peak concurrent Git count: 24
  • 169 sampled Git process rows
  • repeated commands remained status --porcelain, rev-parse HEAD, remote -v, rev-parse --git-dir, and config --null --get core.fsmonitor

An immediate follow-up snapshot found:

  • 31 live git.exe processes
  • 19 older than 5 seconds
  • oldest process: 118.59 seconds
  • fresh Git-for-Windows wrapper/child pairs directly rooted under the packaged codex.exe app-server
  • many older children whose recorded parent had already exited

The app-server handle count increased from 490 to 621 during the 45.78-second sample and was 677 at the follow-up snapshot. This short observation is not enough by itself to claim a persistent handle leak, but it confirms substantial process/handle churn.

One tracked workspace still contains an empty/invalid .git directory, so that remains a plausible amplifier. However, the product behavior is unchanged: the app-server continues launching periodic Git metadata batches, and timed-out wrapped children can outlive their parent on Windows.

Conclusion

26.715.7063.0 appears to mitigate the synchronous HID freeze, but it does not include an effective Windows Git process-tree cleanup or invalid-repository backoff fix. The focused Windows cleanup implementation remains available here:

https://github.com/areslp/codex/commit/b8d7f3c58da35b48d96bf6fb1ed5ed721c2a4fa8

PR #30235 has now received a maintainer approval, but it remains open and Unix-only. If maintainers want the Windows equivalent submitted, an invitation would let me open the focused PR immediately.

areslp · 1 month ago

Follow-up after updating the same Windows host to the current Microsoft Store package.

Current build

  • Package: OpenAI.Codex_26.721.3996.0_x64__2p2nqsd0c76g0
  • Windows 11 x64
  • The original empty marker directory D:\work\.git still exists and still has zero children.

Idle/periodic path is substantially improved

A 55.82-second read-only external sample while the app was naturally idle observed:

  • 4 distinct git.exe PIDs, peak concurrent count 2
  • 5 distinct taskkill.exe PIDs, peak concurrent count 2
  • zero residual Git/taskkill processes
  • main window responsive in 152/152 checks

This is dramatically better than the sustained process storms reproduced in earlier packages.

Session switching still causes visible stutter and a process burst

The user still perceives a short but obvious freeze when switching desktop sessions/threads. I ran a second 60.82-second, 250 ms external process sample while reproducing session switching:

  • 10 distinct git.exe PIDs
  • 11 distinct taskkill.exe PIDs
  • peak concurrent Git count: 2
  • peak concurrent taskkill count: 3
  • the activity was concentrated in a roughly 12-second window, from 23:17:48.859 through 23:18:00.567 local time
  • zero residual Git/taskkill processes at the end
  • main window remained Responding=True in 172/172 checks
  • main-window handle count remained flat at 258

The important distinction is that this no longer looks like the old long-lived process accumulation, but it is also not fully fixed. Session switching still coincides with a short burst of Git and cleanup processes, and the user-visible stall is shorter than Windows' coarse Responding/hang detection.

The current desktop log files for this process were still zero bytes/unflushed during the capture, so I cannot yet prove from logs whether this burst is specifically thread/list, rollout metadata repair, or Git enrichment. The external timing correlation is reproducible, but I do not want to overstate the exact internal call path without flushed logs or ETW.

Current conclusion

The 3996 package appears to have strongly improved the idle/periodic Git storm on this machine, but the latency-sensitive session-switch path still stutters and still launches a concentrated Git/taskkill burst. Please keep session switching and active-agent work as separate acceptance paths; a clean idle sample does not cover either one.

areslp · 1 month ago

Follow-up after several additional Store updates: the same Windows host is now running OpenAI.Codex_26.721.4979.0_x64, and the app feels materially slower again, particularly when switching sessions.

Git/process-tree control

A 60.70-second, 250 ms read-only sample observed:

  • root window responsive in 184/184 checks
  • 1 distinct git.exe, peak 1
  • 2 distinct taskkill.exe, peak 2
  • zero residual Git/taskkill processes

Therefore the old sustained idle Git process storm was not active in this window. The public Git timeout implementation still lacks Windows process-tree cleanup, so this does not close the Git bug; it only narrows the current 4979 slowdown to a different active path.

Renderer/app-server amplification

The same live sample recorded:

  • aggregate ChatGPT/Electron working-set peak: about 2,087.5 MiB
  • packaged app-server: about 650.1 MiB working set / 1,152.4 MiB private memory
  • three heavy renderers at roughly 682.6, 480.1, and 349.4 MiB working set

The flushed 4979 desktop log contained:

  • 420 thread/list responses
  • average 35.1 ms, p95 80 ms, maximum 457 ms
  • bursts up to 16 thread/list responses in one second

Individual responses are usually short, but the redundant bursts add foreground work during navigation/session switching.

Local config is still being overridden

Although concurrent_reasoning_summaries = false remains configured, the renderer resolved the feature to true 413 times and to false zero times. The same log had 15,123 reasoning-related rows and 512 ResizeObserver-loop errors. Reasoning completion rows were replicated about 2.92 times per unique item across primary and hidden overlay/dictation renderers.

The full current-build evidence is posted here:
https://github.com/openai/codex/issues/33996#issuecomment-5084433882

Current conclusion

There are at least two separate Windows acceptance paths:

  1. Git/taskkill lifecycle and cleanup during active work.
  2. Desktop renderer/session-navigation performance.

4979 looked clean for idle Git in this sample, but the second path has regressed: session switching still stutters, remote reasoning-summary enablement overrides the local config, renderer work is duplicated, and the long-lived process footprint exceeds 2 GiB.

Please do not treat a clean idle Git sample or Responding=True as evidence that the Windows desktop performance issue is resolved.

v2-share · 22 days ago

Additional evidence from current Windows build

I am adding this to the existing issue because the symptom matches the Windows chat-switching/UI stutter described here. This is not a new issue.

Environment and symptom

  • Windows desktop app, Microsoft Store build 26.730.8199.0.
  • After a clean launch, mouse/input lag is most noticeable shortly after opening the app and can recur when switching conversations. The behavior is intermittent and may clear after a short period.

Observed timings from the existing local trace

  • thread/resume: 1,177 ms and 1,551 ms, with additional calls around 1.0-1.4 s.
  • plugin/list: 1,601 ms, with additional calls at 2,385 ms, 2,786 ms, and 3,666 ms.
  • config/read: approximately 690-1,102 ms.
  • plugin/installed: approximately 733-1,102 ms.
  • main_thread_jank_snapshot: 4 occurrences.

Interpretation

These timings coincide with conversation restoration/history handling and plugin/config loading during the UI stall. They suggest UI/main-thread contention around thread switching, but do not by themselves prove a single root cause.

Distinction from the older WMI reports

On the same current build, the clean-start trace did not show electron-sampler snapshot failures, WMI Event 5858, a PowerShell/WMI snapshot storm, or taskkill.exe/conhost.exe/git.exe process storms. The current chat-switching lag therefore appears to be a separate or later Windows UI performance path rather than the older WMI sampler issue.

Related reports that seem relevant: #29187 and #29590.