openai / openai/codex

Align wait_agent default timeout with prompt-cache TTL (30 min on GPT-5.6+) to cut parent-agent polling cost

Open
#41,875 3 comments 2 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

CLI enhancement performance rate-limits subagent
Dominant language
Rust
Stars
125k
Forks
19.4k
PR merge metrics
PR metrics pending

Description

What variant of Codex are you using?

CLI (multi-agent / collab mode, GPT-5.6 family)

What feature would you like to see?

Summary: Raise the wait_agent default timeout so the parent-agent polling cadence aligns with the model's prompt-cache TTL (30 min on GPT-5.6+), or make the harness TTL-aware. Today's 30 s default burns parent-agent tokens at ~40 no-op model turns per 20 minutes of waiting, all of which are avoidable.

Background (evidence from existing reports)

wait_agent is already event-driven internally (status watch channels; it returns early on completion), but each timeout expiry returns a timed_out result that re-enters the parent model with the full conversation context. With the 30 s default, a long-running subagent produces a steady stream of no-op parent turns. This is well documented:

  • #37299: 83% of wait_agent calls ended in timed_out; each poll re-meters ~140k tokens of context (97%+ cached); 90% of a weekly allowance consumed in 15.5 h.
  • #35259: across a full week window, wait/status-only turns accounted for 19.8% of all raw token volume (96.8% of it cached input), ≈3,948 credits on the public rate card.
  • #39854: ~678M tokens for a small task, 98.4% cached input. Per the official credit rate card (help.openai.com, "ChatGPT Rate Card"), cached input is metered at ~10% of the input rate (e.g. GPT-5.3-Codex: 43.75 input / 4.375 cached / 350 output credits per 1M) — the quota exhaustion here came from the absolute cached volume (~666M tokens), not from a missing cached discount.
  • #18394: requests a configurable default timeout (the v2 config knobs default/min/max_wait_timeout_ms now exist; thanks — but the default is still 30 s, and the v1 namespace constants in multi_agents_common.rs remain hardcoded).

What is missing from the discussion so far: the cache-TTL dimension

All quantified reports observe polling cadences of 10–60 s. That is far below any cache TTL, so existing measurements only capture the regime where the prefix never falls out of cache. The interaction between wait interval and cache lifetime has not been analyzed.

GPT-5.6-and-later models guarantee a minimum 30-minute prompt cache lifetime (prompt_cache_options.ttl, only supported value 30m, also the default; per the OpenAI prompt-caching docs). Once wait intervals approach or exceed that TTL, each parent turn pays full uncached input price to rebuild the prefix.

A simple per-hour cost model for a parent holding context C while waiting (cached input ≈ 0.1× uncached price):

  • 30 s interval (current default): 120 turns/h × 0.1·pC = 12 pC/h
  • 20 min interval (keep-alive, every turn cache-hit): 3 × 0.1·pC = 0.3 pC/h
  • ~28 min interval (just under TTL with safety margin): ≈ 0.21 pC/h — the cost optimum
  • 60 min interval (every turn a cache miss, full-price refill): 1 × 1.0·pC = 1.0 pC/h

Two useful invariants from this model:

  1. Even in the worst case (the TTL assumption is wrong and every 20-min turn misses), a 20-min interval costs 3 × 1.0 = 3 pC/h — still 4× cheaper than the best case of the current 30 s default (12 pC/h, all hits). The 30 s default is dominated regardless of TTL behavior.
  2. Within the 1 h hard cap on timeout_ms, a keep-alive interval below TTL is structurally cheaper than any miss interval: at a 0.1 cached discount, a miss interval only wins if it exceeds 10× TTL (10 h) — unreachable.

Caveat, stated separately from the evidence: under the official credit rate card, cached input is metered at ~10% of the input rate, so staying cache-hot is a ~10x difference under quota metering too; what remains officially unspecified is how cached context is weighted inside the included 5-hour/weekly subscription limits (asked in #37299, unanswered; the rate card covers credit-based usage). Regardless of that weighting, turn-count reduction dominates under every metering regime, and for intervals ≤ ~25 min both goals align (fewer turns AND cache-hot).

Request

  1. Raise the default wait_agent timeout for models with a known cache TTL (30 min on GPT-5.6+) from 30 s to a TTL-aligned value (~20–25 min), or surface the cache-TTL consideration in the tool description so the model scales timeout_ms accordingly (the collab prompt already says the value "should be wisely scaled" — the default undercuts that guidance).
  2. Alternatively/additionally, adopt the stronger fix already proposed in #37299 / #35259: don't re-enter the model at all when a wait_agent timeout produced no state change — the harness already knows nothing happened.
  3. Align the v1 multi-agent namespace with the v2 config knobs — DEFAULT_WAIT_TIMEOUT_MS = 30_000 in multi_agents_common.rs is hardcoded and ignores [features.multi_agent_v2] settings, so users on the v1 toolset cannot tune this without patching source (noted in #18394).
  4. When documenting the knobs, mention the quota-vs-cost trade-off above so users can pick min_wait_timeout_ms / default_wait_timeout_ms deliberately (quota-constrained: larger; cost-constrained: just under TTL).
Additional information
  • Cache TTL reference: OpenAI prompt caching documentation (prompt_cache_options.ttl, 30m default/only value on GPT-5.6+). On pre-5.6 models the effective TTL is 5–10 min, where a 20-min interval would miss every turn — hence request #1 is phrased per-model-family, and the harness knows which model is in use.
  • The 30 s constant also propagates into the tool schema default shown to the model (spec.rs passes default_timeout_ms), so the model tends to inherit the 30 s cadence even when it could pass a larger value.
  • Related: #18394 (configurable default), #37299 (no-op turns shouldn't re-enter the model), #35259 (19.8% volume from wait/status turns), #39854 / #41817 / #35108 (excess consumption reports), #33485 (UX for wait spam).

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.

Research direction

Start by reading the hardcoded default in multi_agents_common.rs and how spec.rs propagates default_timeout_ms into the tool schema, then compare them with the v2 wait-timeout knobs described in the issue. Trace the wait_agent timeout and no-op re-entry behavior before choosing the supported approach. Done means the agreed TTL-aware or configurable behavior is implemented consistently and its quota/cost trade-off is documented.

Written by the indexing model from the issue text.

Assessment

Tech stack
rust
Domain
cli, performance, tooling
Issue type
Feature
Difficulty
5/5
Estimated time
Over a week
Activity status
Active
Clarity
Mostly clear
Newbie friendliness
42/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.