Skip to course content
Free LLMOps course

LLMOps for Reliable AI Applications

Unit 08.03: Rate limits and graceful degradation

The provider will rate limit you, and what happens next is a design decision you should make before it does.

A ladder, not a binary

Different upstream statuses call for different responses, and degradation has several rungs between working and broken.

The code lists four statuses and a four-rung ladder.

RESPONSES = [
    (200, "ok",              "serve"),
    (429, "rate limited",    "back off, retry with jitter, then degrade"),
    (503, "provider down",   "degrade immediately"),
    (408, "timeout",         "retry once, then degrade"),
]
print(f"{'status':>7} {'meaning':16} response")
for status, meaning, response in RESPONSES:
    print(f"{status:>7} {meaning:16} {response}")

DEGRADED = [
    ("serve from cache if a fresh-enough entry exists", "best"),
    ("return retrieved passages without a generated answer", "good"),
    ("state that the assistant is unavailable and offer the doc link", "acceptable"),
    ("show a spinner until it times out", "worst"),
]
print("\ndegradation ladder:")
for option, quality in DEGRADED:
    print(f"   {quality:11} {option}")

# The second rung is the useful one and is usually skipped. Retrieval still
# works when the model provider is down, and passages with citations are a real
# answer to most questions -- just not a written one.

The second rung is the useful one and is usually skipped: return the retrieved passages without a generated answer. Retrieval still works when the model provider is down, and passages with citations answer most questions - just not in prose.

The bottom rung is what most systems do by default. A spinner that times out gives the user nothing and costs them the wait, which is strictly worse than saying so immediately.

The mistake this prevents

The mistake is retrying a 503 the way you retry a 429. A rate limit clears with backoff; a provider outage does not, and retrying through it multiplies the load on a service that is already failing while the user waits.

Takeaway

Distinguish rate limits from outages and build a degradation ladder. Returning retrieved passages without a generated answer is a real fallback and the one most systems never build.