Repository navigation
Windows Desktop UI lags during 100-thread attachment request bursts and app-server queue saturation #48917
Description
Summary
Codex Desktop on Windows 10 becomes sluggish across all chats. Opening menus or Settings is especially slow. Restarting the app did not resolve it. During a captured Settings interaction, the desktop renderer had a CPU burst and the app-server request queue filled with thread/attachment/list calls during the same UI activity as a thread/list response.
Environment
- Windows 10 Pro 22H2, build 19045, x64
- Codex Desktop Windows package:
OpenAI.Codex 26.924.2738.0(verified from the running executable path) - Desktop log build number:
11645 - Local state: 3,182 total threads, 2,719 not archived
- Local
thread_attachmentstable has 0 rows (this does not establish that no other attachment source exists)
Reproduction
- Open Codex Desktop with this existing local chat history.
- Open a menu or Settings. The whole Codex UI is sluggish; the behavior affects all chats.
- Restart Codex and repeat. The lag remains.
Captured evidence
At 2026-09-28 16:12 Asia/Shanghai (08:12 UTC), while opening Settings:
- Main renderer CPU increased by 2.14 CPU-seconds during one wall-clock second. Its working set rose from about 632 MB to 722 MB.
thread/listcompleted in 28 ms at 08:12:11.392 UTC.- The surrounding burst logged
thread/attachment/listfor 100 distinct conversation IDs (166 log lines). The first queue rejections were logged at 08:12:11.373 UTC, before thethread/listresponse. These events coincide; the log does not prove that the list response caused the attachment requests. - The app-server client queue reached 64 queued interactive requests with 4 in flight. 33 attachment-list requests were rejected with
App server request queue is full(-32001).
A separate burst at about 08:11:26 UTC also covered 100 distinct conversation IDs and had 18 queue-full rejections. This indicates the fan-out is not specific to Settings. The exact UI trigger and source-code cause are not established.
During idle sampling after restart, the renderer used only 0.30 CPU-seconds across 6 seconds. System RAM and disk were not saturated. Thus the observed load is intermittent and coincides with request bursts, rather than constant CPU saturation.
The logs also show an unrelated-looking git-init-watcher retry every five seconds against a malformed path formed by joining two absolute Windows paths. Its relation to the UI lag is unproven.
Expected behavior
Opening menus and Settings should remain responsive with a large local chat history. UI activity should not issue enough simultaneous per-thread attachment requests to exhaust the interactive request queue.
Request
Please investigate which UI path issues attachment-list requests for this stable set of 100 threads, and whether they can be deduplicated, deferred until needed, or concurrency-limited. Please advise whether there is a supported user-side mitigation and which build contains a fix.
Related broader reports: #21211 (thread metadata/history performance), #20214 (Windows UI stutter). Those do not appear to document this exact 100-thread attachment-list burst and queue rejection.
No chat transcript, conversation ID, account detail, credential, full log, or personal filesystem path is included. Prepared with AI assistance at the user's request.
Activity
[-]Windows Desktop UI lags as thread-list refresh fans out 100 attachment requests and fills app-server queue[/-][+]Windows Desktop UI lags during 100-thread attachment request bursts and app-server queue saturation[/+]heznpc commentedon Sep 28, 2026
Independent macOS corroboration: ChatGPT Desktop 26.924.22138, build 11645, on macOS 27.0 / Apple Silicon / 16 GB RAM shows the same
thread/attachment/listqueue-saturation pattern reported here on Windows.The September 28, 2026 UTC logs contain 539 distinct failed request IDs, deduplicated across warning/failure entries, with
-32001: App server request queue is full. This is a local JSON-RPC queue rejection, distinct from an HTTP 429 quota response. The 539 failures span historical bursts; they are not simultaneous requests or evidence of a continuous current failure.Associated rejection records show 4 requests in flight and 64 queued interactive requests, with
priority=interactiveandreason=queue-full. For example, the four-second window beginning 13:34:22 UTC includes attachment-list logs for 249 distinct conversations and 183 distinct failed requests.The inspected installed query handles worktree and pull-request attachment metadata and uses
refetchOnMount: always. Its method name should not be interpreted as image-upload traffic. This source observation does not identify the action that triggered the bursts.Causal limit: these historical windows were not synchronized with UI actions or the separate renderer recording. They establish queue saturation on macOS, but do not establish its trigger or contribution to UI latency.
Investigation request: please include macOS and trace which consumers initiate these requests, particularly mounted offscreen chat rows. Evaluate deduplication and bounded background concurrency while preserving active-chat capacity. These are investigation directions; no fix has been validated. Validate changes against both queue rejections and interaction latency with the same populated history.
Additional burst counts — September 28, 2026 UTC
End timestamps are exclusive. Conversation counts cover attachment-list logs; failure counts use distinct request IDs.
Only aggregate measurements are included; no raw logs, identifiers, transcripts or local paths are shared.
ninosat00 commentedon Oct 17, 2026
Additional evidence: current Windows build and isolated scheduler reproduction
The same
thread/attachment/listqueue saturation is still observable on Codex Desktop 26.1013.40934, build 20770, Windows, production channel. The configured updater reportedup_to_dateon October 17, 2026.Observed incident
The October 17 startup log contains 54
queue-fullrejection records forthread/attachment/listwithin one short burst. This is a historical incident in the sampled logs, not evidence of a continuously full queue. No new rejections were observed in the later diagnostic window. The persistent message queue was empty; it is a different queue from the client request scheduler.Read-only source inspection
In this installed build, the client scheduler has an interactive backlog limit of 64. Attachment-list requests use interactive priority by default and are absent from the coalescible-method set. The inspected attachment-query call site has no shared per-host concurrency bound before admission.
This identifies a plausible saturation mechanism. It does not establish every UI trigger or prove that all Desktop latency has the same cause.
Controlled reproduction
Only the installed scheduler class and its constants were extracted read-only and evaluated in an isolated JavaScript VM. No live app connection, filesystem or network access was provided to that VM. The transport was a stub: dispatch marked the request sent; completion ran on the next
setImmediatecallback. The requests used 200 unique synthetic IDs and methodthread/attachment/list.Reproduction recipe: instantiate the scheduler, synchronously enqueue 200 distinct attachment-list operations using the stub above, await settlement, then repeat with each enqueue operation admitted through one shared two-slot limiter for the host. Both runs finish with all scheduler queues empty. This demonstrates admission overflow under a synthetic burst; it is not a UI benchmark or an end-to-end production fix.
Separate candidate-limiter tests passed for cancellation while waiting, releasing slots after failures, and independent hosts. A real native stdio app-server also completed metadata and attachment-list reads for 24 recent/historic chats at concurrency 2, without chat or attachment writes. That stdio check bypasses the Electron scheduler and therefore does not certify Desktop recovery.
Suggested integration and validation
Share a small per-host limiter across attachment-page consumers, before
sendRequestreaches the client scheduler. Conceptually:Preserve cancellation, pagination, retries and query invalidation; keep admission protection and capacity for active-chat actions. Validate cold startup with populated history, remounted/offscreen rows and multiple windows, measuring queue rejections and interaction latency together.
The installed signed app, admission experiments and user configuration were not modified. The limiter is a local candidate requiring vendor integration. No raw logs, chat identifiers, transcripts, account details, private configuration or personal filesystem paths are included. Prepared with Codex assistance.
xiru0834-eng commentedon Oct 19, 2026
October 19 recurrence: sending stalls, 1,318 queue rejections, and stale queued-submission error
Environment: Windows x64, Codex Desktop 26.1013.40934 / build 20770, production channel; the configured updater still reported
up_to_dateon October 19. Backend:codex-cli 0.163.0-alpha.10.2. Follow-up messages use queue mode, which the user wants to retain.User impact: ordinary coding work repeatedly leaves message submission spinning; the user also reports being unable to attach/send files. Restarting temporarily restores use, but the problem recurs. There is no deterministic minimal UI trigger yet.
Two new captured incidents (UTC, October 19, 2026)
app_server_client_request_queue_rejectedrecords, counted once at the rejection log rather than also counting failure echoes. Breakdown: 1,290thread/attachment/list, 10config/read, 6thread/queue/list, 4thread/list, 2 eachconfigRequirements/readandfs/createDirectory, and 1 eachfs/watch,thread/fork,app/installed,model/list. Rejections show 64 queued interactive requests and up to 8 requests in flight.thread/attachment/list, with 64 queued interactive requests and 7 in flight. A user screenshot taken at about this time showed the pending sender. After restart, at 03:34:19.100, the desktop loggedFailed to send queued message, code-32600, messagequeued submission not found: <redacted>.Sanitized excerpts (identifiers omitted):
A queued submission had been accepted before restart, and the affected conversation was independently observed starting a new turn shortly before the latter error. Thus the error suggests stale/duplicate submission state, but does not establish message loss. Please reconcile frontend queued IDs with server consumption on reconnect so the UI gives an accurate result without encouraging duplicate submissions.
Mechanism and reproduction
Read-only inspection of this installed build confirms the earlier comment's findings: interactive backlog limit 64; attachment-list requests absent from the coalescible-method set; attachment metadata query uses
refetchOnMount: "always"and no shared pre-admission limit at the inspected call site. Cancellation is checked before/after the request but is not passed intosendRequestat that call site.The isolated 200-request scheduler reproduction was rerun with stub completion on the next
setImmediate: 68 succeeded / 132 rejected / peak 4 in flight. Admitting the same workload through a shared two-slot per-host limiter gave 200 succeeded / 0 rejected / peak 2. Waiting cancellation, host isolation and slot release after failure also passed. This is synthetic admission-overflow evidence, not a real UI benchmark.A candidate integration was prepared only in a separate disposable app copy. Its full modified JavaScript passed syntax checking, but the copied client refused to launch because the native ASAR integrity check rejected it. No integrity bypass was attempted, the installed app was not patched, and no end-to-end repair is claimed. A supported vendor build is needed.
Important boundaries and requested fix
thread/attachment/listhandles worktree/PR metadata, not the image-upload transport. The logs establish common request-queue saturation and control-request rejection; they do not independently identify a failed image-upload network request.Only sanitized aggregates, technical excerpts and reproduction results are posted. No screenshot, transcript, conversation/request identifier, account detail, personal path, credential, raw log or dump is uploaded. Prepared with Codex assistance at the user's explicit request.