Codex Desktop repeatedly re-enters the model during wait/status polling, consuming substantial credits
Nobody has claimed this yet.
Assessment
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Newbie friendliness
- 45/100
- Issue type
- Bug
- Clarity
- Mostly clear
- Activity status
- Active
- Tech stack
- rust
- Domain
- ai-infra-agents, tooling
Research direction
Start by tracing the handlers for wait_agent, list_agents, write_stdin, and generic wait in the Rust codebase, then inspect related reports #34468, #33276, #35108, and #13733. Locate existing agent or terminal polling tests and reproduce unchanged-state polling with a long-running task. Done means quiet wait intervals no longer create repeated model turns, with regression coverage for unchanged wait state.
Written by the indexing model from the issue text.
Description
Summary
During intentional Ultra and multi-agent work, Codex Desktop repeatedly re-entered the model merely to wait for agents or poll terminal status. In a corrected reset-to-49%-usage window, model turns whose only tool action was wait/status polling accounted for 19.8% of raw local token volume.
Ultra and multi-agent use were intentional. The suspected defect is not normal agent fan-out; it is repeated model inference during quiet coordination and process-wait intervals, often at 30- or 60-second cadence.
Related reports exist, but this report adds current-build evidence, replay-safe accounting, a full usage-cycle window, tool-level decomposition, a representative long-running trace, and a public-rate-card estimate.
Environment
- ChatGPT Pro
- macOS on Apple silicon
- Codex Desktop 26.721.31836 (build 5828)
- Incident runtime: codex-cli 0.146.0-alpha.3.1
- Mostly GPT-5.6 Sol
What issue are you seeing?
Long-running multi-agent tasks can generate hundreds of distinct model turns that do no substantive work beyond calling one of these tools:
wait_agentlist_agentswrite_stdin- generic
wait
Each polling interval appears to re-enter the model, ingest a large cached conversation prefix, and then make another wait/status call. This can continue for hours while delegated work or a terminal process is still running.
Corrected local evidence
I analyzed local rollout telemetry from one complete weekly reset window, from the reset through the first observed 49% usage state.
The parser:
- excludes copied parent-history prefixes in child rollouts;
- starts each child at its live
task_startedboundary; - ignores unchanged cumulative token snapshots; and
- counts only genuine per-turn token deltas.
Corrected window:
- 10,586 genuine model turns
- 1,382,757,012 raw local tokens
- 43,668,351 uncached input tokens
- 1,335,723,264 cached input tokens
- 3,365,397 output tokens
- 96.83% cached-input share
- 94,241 copied-prefix token records excluded
- 404 duplicate token snapshots excluded
Tool-only wait/status turns:
| Tool group | Turns | Raw local tokens | Uncached input | Cached input | Output | Share of all raw |
|---|---|---|---|---|---|---|
wait_agent / list_agents only |
985 | 142,137,652 | 2,654,345 | 139,365,376 | 117,931 | 10.3% |
write_stdin / wait only |
983 | 131,423,068 | 1,319,437 | 130,028,544 | 75,087 | 9.5% |
| Combined | 1,968 | 273,560,720 | 3,973,782 | 269,393,920 | 193,018 | 19.8% |
Using the current public GPT-5.6 Sol rate card, the combined wait/status subset corresponds to an estimated 3,948 credits. This is a rate-card estimate from local telemetry, not a claim about the private subscription billing ledger.
Representative long-running trace
One child task ran for about 10 hours 55 minutes and contained:
- 1,417 genuine model turns
- 254
wait_agentcalls - 31
list_agentscalls - 316
write_stdincalls - 12 generic
waitcalls - 613 combined wait/status-only turns
- about 93.17 million raw local tokens attributable to those wait/status turns
The wait/status subset was about 45% of that child task's genuine raw token volume. Most agent waits requested only 30 or 60 seconds before another model-mediated poll.
Steps to reproduce
- Start an Ultra task that delegates a genuinely long-running child task.
- Let the child run for at least 30-60 minutes while the parent or another child coordinates it.
- Observe repeated
wait_agent,list_agents,write_stdin, or genericwaitcalls during otherwise quiet intervals. - Inspect per-turn local token deltas, excluding copied child-history prefixes and unchanged cumulative snapshots.
- Note that status-only polling repeatedly creates distinct model turns and reprocesses a large cached context.
Expected behavior
Waiting for an agent or terminal process should be event-driven, or handled by the harness without repeatedly invoking the model. The model should wake when:
- the child or process produces meaningful new output;
- the child completes or requires attention;
- the user sends new input; or
- a deliberately bounded, low-frequency checkpoint is required.
Actual behavior
Quiet wait intervals repeatedly invoke the model so it can issue another polling tool call. Large cached prefixes are charged through the public credit model even though the turns produce almost no substantive user-facing work.
Why this is not ordinary Ultra fan-out
Ultra and explicit multi-agent delegation were intentional, and their extra cost is expected. The anomalous subset here is narrower: nearly one-fifth of corrected raw token volume came from turns whose only action was waiting or checking status.
The same corrected window attributed 68.1% of raw volume to Ultra and 58.7% to subagents. Those figures describe the chosen workload. This issue concerns the avoidable model-mediated polling inside that workload.
Evidence boundary
- These figures come from local rollout telemetry, not OpenAI's internal billing ledger.
- Raw local token volume is not the same as subscription usage.
- The credit figure is an estimate using the published model rate card.
- Copied historical token records were explicitly excluded and are not claimed as billing events.
- I found no evidence here of a silent quota reduction.
- No private prompts, task identifiers, repository names, local paths, account details, or transcript content are included.
Related reports
- #34468 — parent chat polls child agents every minute
- #33276 — wait-for-agents loop drained quota
- #35108 — nested wait-agent polling
- #13733 — terminal polling
- #18394 — default wait timeout
- #34361 — replay attribution work
Suggested fix direction
- Make agent and terminal waits event-driven inside the harness.
- Avoid a fresh model call when no meaningful state has changed.
- Coalesce repeated status checks and apply backoff for long-running work.
- Surface wait/polling usage separately in diagnostics.
- Add regression coverage asserting that unchanged wait state does not create repeated billable model turns.
- Dominant language
- Rust
- Stars
- 125k
- Forks
- 19.5k
- Avg merge
- 1m
- Merged PRs (30d)
- 1k
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
More from openai/codex
-
enhancement remote
Difficulty 2/5 1-3 hours Newbie friendliness 68/100
-
bug CLI windows-os
Difficulty 2/5 1-3 hours Newbie friendliness 76/100
-
macOS sandbox blocks hw.optional.arm64 sysctl, causing Flutter to misdetect Apple Silicon as x64 Openbug CLI sandbox
Difficulty 2/5 1-3 hours Newbie friendliness 78/100
-
bug CLI TUI
Difficulty 2/5 1-3 hours Newbie friendliness 90/100
-
CLI config enhancement skills
Difficulty 2/5 1-3 hours Newbie friendliness 84/100
Similar issues
-
Difficulty 2/5 1-3 hours Newbie friendliness 86/100
kwakseongjae/auto-hwp#319 ·
-
area:cli bug filter-quality good first issue priority:medium
Difficulty 2/5 1-3 hours Newbie friendliness 84/100
-
Difficulty 1/5 Under an hour Newbie friendliness 72/100
bevyengine/bevy#25861 ·
-
comp-datalake
Difficulty 2/5 1-3 hours Newbie friendliness 88/100
ClickHouse/ClickHouse#121222 ·
-
A-linter
Difficulty 2/5 1-3 hours Newbie friendliness 72/100
oxc-project/oxc#26863 ·