[Windows App] skills/list blocks thread switching for 14–22s across 29 workspaces

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

Codex App: 26.707.9981.0
Platform: Windows 11 x64

During a thread switch:

  • thread/list: 74 ms
  • skills/list: 22,154 ms, cwdsCount=29
  • thread/read: 75 ms, but only starts after skills/list completes
  • thread/resume: 60 ms

A second skills/list request took 14,240 ms and reported
missingShortDescriptionCount=3403.

mcpServerStatus/list also took 12,469 ms and cold-started 10 MCP servers.

Local inventory:

  • 3,150 threads
  • 29 workspaces included in skills/list
  • 104 installed plugin/global SKILL.md files

Related reports:

  • #14469: Similar chat-switch lag in the Codex desktop app (closed as a duplicate)
  • #21441: Merged optimization that added bounded concurrency to skills/list

Important: #21441 already limits skills/list CWD loading to five concurrent tasks, but the current app still observes 14–22 seconds of latency. This suggests that increasing concurrency alone is insufficient.

Suggested fix direction:

  • The Desktop app should not block thread switching on the completion of skills/list.
  • The app-server should cache or deduplicate shared global and plugin skill metadata across CWDs, loading only CWD-specific overlays.
  • Add a cold-start performance test covering 29 CWDs and more than 100 shared skills.
  • mcpServerStatus/list should not cold-start every configured MCP server during a status check.

Relevant public code locations:

  • catalog_processor.rs:

https://github.com/openai/codex/blob/main/codex-rs/app-server/src/request_processors/catalog_processor.rs

  • skills_list.rs:

https://github.com/openai/codex/blob/main/codex-rs/app-server/tests/suite/v2/skills_list.rs

I understand that external pull requests are currently accepted by invitation only. I am submitting this issue first to share the reproduction data and proposed direction.

View original on GitHub ↗

4 Comments

github-actions[bot] contributor · 1 month ago

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

  • #32154
  • #32654

Powered by Codex Action

zhangputing · 1 month ago

Thanks for linking these related reports. This issue overlaps with #32154 and #32654, but it is not a duplicate.

The main difference is that this report is from a native Windows 11 environment, not WSL2 or macOS.

In my measurements:

  • thread/resume: 60 ms
  • thread/read: 75 ms
  • skills/list: 14–22 seconds across 29 CWDs

Therefore, the primary thread-switching delay occurs before thread/read and thread/resume. The 12.5-second mcpServerStatus/list request is a secondary issue rather than the main cause of this report.

cary-hu · 1 month ago

Same issue here, Each time open new session, The typing will stuck and stopped for a while.

NOirBRight · 1 month ago

Additional root-cause evidence from Windows 11 x64 with Codex App 26.707.12708.0 and bundled app-server 0.144.5 (rust-v0.144.5, commit 87db9bc18ba5bc82c1cb4e4381b44f693ee35623).

Desktop request chain and exact cwdsCount source

Inspection of the packaged Desktop ASAR shows this chain:

  1. WORKSPACE_ROOT_OPTIONS maps to electron-saved-workspace-roots.
  2. The workspace-root-options main-process handler returns that entire saved-root array.
  3. The default Renderer skills hook uses workspace-root-options.data.roots when no explicit CWD is supplied.
  4. It sends list-skills-for-host({ cwds: roots }).
  5. The request logger reports cwdsCount = roots.length before sending skills/list.

Therefore:

cwdsCount = electron-saved-workspace-roots.length

It is not the active-workspace count. A Git worktree contributes only if it is persisted as a saved workspace.

App-server duplication boundary

The matching public source explains the near-linear amplification:

This means cold plugin roots may be parsed during capability/root discovery and then parsed again by SkillsService.

Runtime count correlation

A historical run with 11 saved roots reported:

cwdsCount=11
missingShortDescriptionCount=1304

After a clean setup with one saved root, the same build reports 114-116 missing descriptions per request.

1304 / 11 = 118.5

That close match is runtime evidence that shared global/plugin skills are returned and validated once per CWD, rather than once plus a CWD-local overlay.

Suggested implementation boundary

  • Build one immutable global/system snapshot per relevant config.
  • Build one plugin snapshot keyed by plugin ID/version/path and pass PluginSkillSnapshots into the skills load.
  • For each CWD, discover only repo-local roots and merge that overlay with the shared snapshots.
  • Add per-root singleflight so concurrent cold CWDs cannot parse the same shared root.
  • Do not gate thread switching on a cold full skills/list; stale cached data can render while an incremental refresh completes.

This preserves normal multi-project and multi-worktree use without reducing workspace count as the solution.