Skip to article
API429 / Field notes

AI API Hedged Requests: Cut Tail Latency Without 429 Storms

Evaluate delayed backup requests for latency-sensitive AI API calls using application-side hedge budgets, cancellation, and reconciliation.

Hourglass and a queue of paper request cards
Editorial photo illustration: Hourglass and a queue of paper request cards. Topic: AI API Hedged Requests: Cut Tail Latency Without 429 Storms.

Hedged requests can reduce tail latency for interactive workloads, but they also multiply token consumption and request volume if triggered without strict application-side controls. Unlike a sequential retry that waits for a terminal failure, a hedged request dispatches a delayed backup call while the primary request is still in flight, accepts the first valid completion, and cancels or discards the slower attempt.

Because every backup dispatch is a real billable API request, hedging belongs inside your application's execution layer with an explicit hedge budget, route independence check, and side-effect guard. Review the API429 documentation and model catalog to inspect published endpoints and model metadata, and pair hedging with the application retry budget policy so backup calls and retries never compound unchecked.

Separate delayed hedging from sequential retries and request coalescing

Teams frequently confuse three distinct concurrency patterns that solve different operational problems:

  • Delayed hedging dispatches a second call for the same logical task after the primary call exceeds a high-percentile latency threshold (such as p95), racing two independent routes to bound tail latency.
  • Sequential retry waits until the first attempt returns a terminal status (such as HTTP 429 or 503) and a valid backoff interval before submitting another attempt, as covered in the retry budget guide.
  • In-flight request coalescing merges identical concurrent calls from authorized callers into a single upstream request, as detailed in the request coalescing guide.

Hedging increases upstream load to buy lower tail latency. If a provider or route is already returning 429 Too Many Requests (RFC 6585 Section 4) or advertising a Retry-After cooldown (RFC 9110 Section 10.2.3), dispatching a hedged request into that same capacity pool accelerates exhaustion. Under Google Gemini API rate limits, direct Google project quotas track requests per minute (RPM), input tokens per minute (input TPM), and requests per day (RPD) at the project level—meaning two simultaneous requests against the same project consume double the input token rate immediately.

Decision table: when to allow or block a hedged AI API call

Your worker should evaluate workload priority, route independence, schema compatibility, and remaining token allowance before starting a backup timer:

Workload and route state Hedge decision Application control rationale
Interactive user turn, primary exceeds p95 delay, approved alternate route is healthy Allow 1 delayed hedge Bounded extra cost is justified to protect interactive latency
Background batch enrichment, queue worker, or asynchronous report Block hedging Throughput and unit cost matter more than single-request tail latency
Primary or alternate route recently returned HTTP 429 or is in cooldown Block hedging Hedging during rate-limit pressure turns latency spikes into 429 storms
Streaming response has already emitted user-visible tokens Block hedging Switching mid-stream corrupts output continuity and wastes generated tokens
Tool-calling turn that triggers external mutations without idempotency Block hedging Two concurrent completions can execute duplicate writes, emails, or charges
Structured JSON extraction where alternate model lacks verified schema support Block hedging A fast response that fails JSON Schema validation is still a failed turn
Remaining task token or monetary budget cannot cover two full calls Block hedging Both calls may run to completion before cancellation takes effect

Enforce a rolling hedge budget and side-effect boundaries

In The Tail at Scale, delaying backup requests until the primary request exceeds the 95th percentile latency limits extra load to roughly 5% of traffic. For LLM APIs, your application should enforce an explicit rolling window (for example, allowing at most 5% of interactive requests over the last 1,000 calls to spawn a hedge) alongside per-request token reservation.

Before the hedge timer fires, verify three invariants in application code:

  1. Both calls fit the task cost allowance: Even if the winning response cancels the losing HTTP connection via AbortController or task cancellation, the upstream provider may have already processed the prompt tokens and part of the completion. Reserve enough budget for both calls up front, following the AI API cost guardrails guide.
  2. Downstream side effects are gated by a single winner token: Bind every logical turn to an operation key so only the first validated completion can commit state, and reconcile any ambiguous timeout using the application idempotency ledger.
  3. The backup route satisfies the exact workload contract: Confirm that the alternate model ID is present in a fresh GET /v1/models observation and passes your scoped workload health checks and structured-output pipeline contract.

Runnable offline Python hedge admission evaluator

The standalone Python module below evaluates whether an in-flight primary request is eligible for a delayed backup call based on elapsed latency, rolling hedge ratio, cooldown signals, streaming progress, and reserved budget. It runs offline with synthetic observations:

from dataclasses import dataclass

@dataclass(frozen=True)
class HedgeDecision:
    allow_hedge: bool
    reason: str
    reserved_extra_tokens: int

def evaluate_hedge_candidate(
    *,
    interactive: bool,
    elapsed_ms: float,
    p95_threshold_ms: float,
    total_deadline_ms: float,
    backup_call_allowance_ms: float,
    stream_chunks_emitted: int,
    primary_rate_limited: bool,
    backup_route_healthy: bool,
    backup_contract_verified: bool,
    recent_requests: int,
    recent_hedges: int,
    max_hedge_ratio: float,
    estimated_call_tokens: int,
    remaining_token_budget: int,
) -> HedgeDecision:
    if not interactive:
        return HedgeDecision(False, "non_interactive_workload", 0)
    if stream_chunks_emitted > 0:
        return HedgeDecision(False, "stream_already_started", 0)
    if primary_rate_limited or not backup_route_healthy:
        return HedgeDecision(False, "route_under_pressure_or_unhealthy", 0)
    if not backup_contract_verified:
        return HedgeDecision(False, "backup_contract_unverified", 0)
    if elapsed_ms < p95_threshold_ms:
        return HedgeDecision(False, "below_p95_delay_threshold", 0)
    if elapsed_ms + backup_call_allowance_ms > total_deadline_ms:
        return HedgeDecision(False, "insufficient_remaining_deadline", 0)
    projected_ratio = (recent_hedges + 1) / max(1, recent_requests)
    if projected_ratio > max_hedge_ratio:
        return HedgeDecision(False, "rolling_hedge_budget_exhausted", 0)
    if remaining_token_budget < estimated_call_tokens:
        return HedgeDecision(False, "insufficient_token_budget_for_backup", 0)
    return HedgeDecision(True, "hedge_admitted", estimated_call_tokens)

if __name__ == "__main__":
    admitted = evaluate_hedge_candidate(
        interactive=True,
        elapsed_ms=1850.0,
        p95_threshold_ms=1600.0,
        total_deadline_ms=4500.0,
        backup_call_allowance_ms=1800.0,
        stream_chunks_emitted=0,
        primary_rate_limited=False,
        backup_route_healthy=True,
        backup_contract_verified=True,
        recent_requests=200,
        recent_hedges=6,
        max_hedge_ratio=0.05,
        estimated_call_tokens=2400,
        remaining_token_budget=6000,
    )
    blocked = evaluate_hedge_candidate(
        interactive=True,
        elapsed_ms=1900.0,
        p95_threshold_ms=1600.0,
        total_deadline_ms=4500.0,
        backup_call_allowance_ms=1800.0,
        stream_chunks_emitted=0,
        primary_rate_limited=True,
        backup_route_healthy=True,
        backup_contract_verified=True,
        recent_requests=200,
        recent_hedges=6,
        max_hedge_ratio=0.05,
        estimated_call_tokens=2400,
        remaining_token_budget=6000,
    )
    print("Admitted candidate:", admitted)
    print("Blocked on 429 pressure:", blocked)

Where API429 fits in a hedged request architecture

API429 provides an OpenAI-compatible gateway boundary—exposing GET /v1/models, POST /v1/chat/completions, and GET /api/client/balance—so your application can address approved models across providers such as Google Gemini, OpenAI, and Anthropic through one client configuration. Check the pricing overview and FAQ to compare model rates and billing units before qualifying a backup model.

Your application remains responsible for setting the hedge timer, cancelling the slower HTTP stream, validating the winning payload before committing side effects, and reconciling billed usage across both attempts.

FAQ

How is a hedged request different from a retry on HTTP 429?

A retry runs only after an attempt fails with an explicit status such as 429 or 503 and respects Retry-After. A hedged request starts while the first call is still running because latency crossed a high-percentile threshold; it should never be used to push duplicate traffic into a rate-limited route.

Does cancelling the slower request eliminate its token cost?

No. Cancelling the client HTTP request stops further response streaming and frees local worker sockets, but the upstream model may have already processed the prompt and generated partial output. Always reserve budget for both calls before dispatching a hedge.

Should streaming chat completions be hedged after tokens arrive?

No. Once the primary stream emits tokens to the caller, starting or switching to a backup stream produces inconsistent text. Limit hedging to time-to-first-token (TTFT) before any chunk is forwarded downstream, or to non-streaming turns.

What telemetry should workers record for hedged requests?

Log a redacted correlation ID, primary and backup model IDs, hedge delay threshold, winner route, cancellation latency, HTTP status codes for both legs, and reconciled token usage—without storing raw prompts or bearer tokens.

Sources & further reading

  1. Google Research — The Tail at Scale
  2. RFC 6585 Section 4 — 429 Too Many Requests
  3. RFC 9110 Section 10.2.3 — Retry-After
  4. Google Gemini API — Rate limits
  5. API429 — Client documentation
  6. API429 — Public OpenAPI specification

Put the next step into practice.

Check model IDs, current pricing and request formats before integrating. Availability can depend on the model and provider route.

Telegram