Codex Desktop repeatedly re-enters the model during wait/status polling, consuming substantial credits

Open
#35,259 27 comments 22 reactions 0 assignees View on GitHub

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

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

app bug rate-limits subagent tool-calls

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_agent
  • list_agents
  • write_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_started boundary;
  • 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_agent calls
  • 31 list_agents calls
  • 316 write_stdin calls
  • 12 generic wait calls
  • 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

  1. Start an Ultra task that delegates a genuinely long-running child task.
  2. Let the child run for at least 30-60 minutes while the parent or another child coordinates it.
  3. Observe repeated wait_agent, list_agents, write_stdin, or generic wait calls during otherwise quiet intervals.
  4. Inspect per-turn local token deltas, excluding copied child-history prefixes and unchanged cumulative snapshots.
  5. 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

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

More from openai/codex

All issues in openai/codex

Similar issues

More Rust issues

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.