[Superseded] Automatic provider failover on ChatGPT usage-limit exhaustion

Resolved 💬 2 comments Opened Jul 11, 2026 by guangxiangdebizi Closed Jul 11, 2026

Feature: automatic model-provider failover on ChatGPT usage-limit exhaustion

What variant of Codex are you using?

Codex CLI and TUI (0.144.1).

What feature would you like to see?

Add an opt-in provider failover policy that keeps the official ChatGPT/OpenAI
provider as the baseline, switches to a user-configured fallback provider when
either the 5-hour or weekly ChatGPT usage window is exhausted, and returns to
the official provider when every exhausted window has reset.

This is different from generic HTTP retry or model rerouting. It is a
quota-aware provider state machine with provider-specific authentication.

Problem

Codex already exposes structured ChatGPT limit data:

  • RateLimitSnapshot.primary for the 5-hour window.
  • RateLimitSnapshot.secondary for the weekly window.
  • used_percent, window_minutes, and resets_at.
  • rate_limit_reached_type.
  • UsageLimitReachedError.resets_at.
  • App-server account/rateLimits/read and

account/rateLimits/updated.

However, when a subscribed user's 5-hour or weekly allocation is exhausted, a
turn stops even if the user has an independently configured API-compatible
provider that could continue the work. Users can manually edit
model_provider, credentials, and provider configuration, but doing so:

  1. Interrupts the current workflow.
  2. Risks sending the wrong credential to a custom base URL.
  3. Requires tracking both reset windows manually.
  4. Does not automatically restore the preferred official provider.

Desired behavior

In automatic mode:

  1. Prefer the configured primary provider (openai in the common case).
  2. Continue using it while every applicable ChatGPT quota window is available.
  3. If either the 5-hour or weekly window reaches its limit, activate the first

eligible fallback provider.

  1. Persist the exhausted windows and their reset timestamps.
  2. Stay on fallback until all exhausted windows have reset.
  3. Probe official availability using the existing structured rate-limit API.
  4. Return to the primary provider automatically.
  5. If the official provider still returns UsageLimitReachedError, immediately

return to fallback and update the reset state.

Manual primary, fallback, and auto overrides should always be available.

Possible configuration

The exact schema is open for discussion. One possible shape:

[provider_failover]
mode = "auto"
primary = "openai"
fallbacks = ["company-proxy"]
fallback_on = ["chatgpt_usage_limit"]
restore = "when_all_exhausted_windows_reset"
max_turn_retries = 1

[model_providers.company-proxy]
name = "Company proxy"
base_url = "https://proxy.example.invalid"
wire_api = "responses"
env_key = "COMPANY_PROXY_API_KEY"
requires_openai_auth = false

Manual CLI/TUI controls could be:

/provider auto
/provider primary
/provider company-proxy

or:

codex --provider-mode auto
codex --provider-mode primary
codex --provider company-proxy

Authentication and security requirements

This feature should not reuse one global credential blindly across providers.

  • ChatGPT bearer/refresh tokens must never be sent to a custom provider URL.
  • A fallback should be eligible only when it has an independent credential

binding, such as its own env_key, provider auth block, or provider-scoped
stored credential.

  • Failover should be disabled with a clear diagnostic if the fallback's auth

cannot be resolved safely.

  • Logs and rollout events should record provider IDs and transition reasons,

but never credentials.

Provider-scoped auth is the main reason this should be designed natively rather
than implemented as a blind retry around the current global auth.json.

Suggested state machine

PrimaryAvailable
  -> PrimaryLimited(exhausted windows + resets_at)
  -> FallbackActive
  -> ProbePrimary(after strictest relevant reset)
  -> PrimaryAvailable

Manual override is orthogonal:

Auto | ForcePrimary | ForceFallback(provider_id)

For two exhausted windows, recovery should use the strict condition:

now >= max(reset timestamp of every exhausted window)

An earlier 5-hour reset must not restore the primary provider while the weekly
window remains exhausted.

Turn continuity

The ideal behavior is to retry the same user turn once after switching the
provider.

To avoid duplicate side effects:

  • Automatic same-turn replay is safe when the usage-limit failure occurs before

any assistant output or tool call is committed.

  • If the failure occurs after side effects, Codex should preserve the thread and

resume with an explicit continuation boundary rather than blindly replaying
the whole turn.

  • Transition loops must be bounded.

User-visible behavior

Codex should emit a concise transition event:

Official ChatGPT weekly limit reached.
Switched to provider "company-proxy" until 2026-07-18 12:00 local time.

On recovery:

Official ChatGPT limits are available again.
Switched back to the primary provider.

/status and app-server thread/account status should expose:

  • provider mode;
  • active provider;
  • transition reason;
  • exhausted windows;
  • next primary probe/reset time.

Acceptance criteria

  • [ ] Official provider remains active when both 5-hour and weekly windows have

quota.

  • [ ] Exhausting either window activates the configured fallback.
  • [ ] Exhausting both windows waits for both resets, not only the earlier one.
  • [ ] Official availability is checked from structured data, not localized

error-string matching.

  • [ ] Recovery returns to the primary provider automatically.
  • [ ] Manual primary/fallback/auto overrides work.
  • [ ] Provider credentials are isolated.
  • [ ] Same-turn retry is bounded and does not duplicate committed tool effects.
  • [ ] TUI, exec mode, and app-server clients receive provider-transition events.
  • [ ] Existing behavior is unchanged when failover is not configured.

Suggested tests

  1. Primary request succeeds: no transition.
  2. Primary returns a 5-hour limit error: fallback receives one retry.
  3. Primary returns a weekly limit error: fallback remains active until weekly

reset.

  1. Both windows are exhausted: earlier reset does not restore primary.
  2. Probe after the strictest reset succeeds: primary is restored.
  3. Probe still reports exhausted: fallback remains active.
  4. Fallback auth missing: fail safely without sending primary credentials.
  5. Failure after a committed tool call: no blind full-turn replay.
  6. Manual override suppresses automatic transitions.
  7. Restart/resume preserves the active failover state.

Related issues and distinction

  • #20310 requests scriptable usage-limit status.
  • #21073 requests auto-resume when a usage limit resets.

This request uses the same structured rate-limit primitives but addresses a
different workflow: continue immediately on a separately authenticated provider
and restore the preferred official provider after quota recovery.

Local workaround

I implemented a PowerShell/Node proof of concept outside Codex that:

  • reads rollout RateLimitSnapshot events;
  • calls account/rateLimits/read through an isolated official app-server;
  • tracks both reset windows;
  • atomically changes local provider profiles;
  • provides auto, official, and proxy overrides;
  • restarts with codex resume --last when run through a managed launcher.

The workaround validates the state-machine behavior, but native support is
needed for safe provider-scoped auth, config reload, and exact same-turn retry.

Reference implementation and validation notes:
https://github.com/guangxiangdebizi/Medical-webwithai/pull/2

View original on GitHub ↗

This issue has 2 comments on GitHub. Read the full discussion on GitHub ↗