C.W.K.
Stream
Lesson 02 of 07 · published

Fallback Chains and Degraded Modes

~14 min · fallback, degraded-mode, reliability

Level 0Observer
0 XP0/64 lessons0/13 achievements
0/150 XP to next level150 XP to go0% complete

Three patterns, three blast radii

Fallback for Claude calls has three flavors. Same provider, smaller model — Sonnet → Haiku when Sonnet is rate-limited. Cross-provider — Anthropic → OpenAI → Gemini for capability-equivalent calls. Async deferral — push the call to Batch API or a queue when sync fails. Each has a different cost story and different UX implications.

Degraded mode is honest UX

If your fallback path returns a lower-quality answer, tell the user. 'Reply generated by Haiku because Sonnet was unavailable' is better than silently shipping a worse answer. cwkPippa surfaces the brain via UI badges so Dad knows when Pippa is running on the smaller model.

Drill it once a quarter

Untested fallbacks have bugs. Every quarter, deliberately disable the primary path in staging and watch the fallback run end-to-end. Bugs you find in a drill are bugs that will not bite you in production.

Principle: Reliability is layered. Fallbacks are the layers; drills are the proof.

Code

Three-step fallback chain·python
from anthropic import Anthropic, RateLimitError, InternalServerError, APIConnectionError

client = Anthropic(max_retries=2)

async def chat_with_fallback(messages):
    # 1) Try the planned tier.
    try:
        return ('sonnet', await call(client, 'claude-sonnet-4-6', messages))
    except (RateLimitError, InternalServerError, APIConnectionError):
        pass
    # 2) Same provider, smaller model.
    try:
        return ('haiku', await call(client, 'claude-haiku-4-5-20251001', messages))
    except (RateLimitError, InternalServerError, APIConnectionError):
        pass
    # 3) Cross-provider.
    return ('openai', await call_openai(messages))
Surface the fallback to the user·typescript
function ResponseBadge({ tier }: { tier: 'sonnet' | 'haiku' | 'openai' }) {
  if (tier === 'sonnet') return null;  // primary path, no badge
  const label =
    tier === 'haiku' ? 'fast mode (smaller model)' : 'fallback provider';
  return (
    <span className="text-xs text-amber-600" title={`Generated via ${tier}`}>
      {label}
    </span>
  );
}

External links

Exercise

Add a quarterly drill to your runbook. The drill: disable the Anthropic API key in staging, run a representative request, confirm the fallback path serves it within SLA. Document who is on call and what they should see.
Hint
If you cannot describe what the user sees during fallback, your degraded UX is undefined — fix that first.

Progress

Progress is local-only — sign in to sync across devices.
Spotted a bug or have feedback on this page?Report an Issue

Comments 0

🔔 Reply notifications (sign in)
Sign inPlease sign in to comment.

No comments yet — be the first.