← Back to Index

15. Fault Tolerance

AI systems must handle failures gracefully. Unlike traditional services where a 500 error is acceptable, AI systems often serve critical decisions (fraud detection, medical triage, autonomous driving) where failing open or returning a wrong answer has real consequences.

Redundancy

Deploy multiple replicas of every component across availability zones or regions.

Retry Strategies

Transient failures (network blips, DB timeouts, GPU OOM) should be retried. But naive retries can overload the system.

# Exponential backoff with jitter
def retry_with_backoff(fn, max_retries=3):
    for attempt in range(max_retries):
        try:
            return fn()
        except TransientError as e:
            if attempt == max_retries - 1:
                raise  # final attempt failed
            wait = (2 ** attempt) * 0.1  # 100ms, 200ms, 400ms
            wait += random.uniform(0, 0.05)  # jitter
            time.sleep(wait)

Circuit Breakers

When a downstream service (e.g., feature store, embedding API) is consistently failing, stop calling it to prevent cascading failures.

# Circuit breaker states for AI inference
CLOSED: Normal operation. Requests flow to feature store.
  If 5 consecutive failures → transition to OPEN

OPEN: Requests bypass feature store. Use default features.
  After 30 seconds → transition to HALF_OPEN

HALF_OPEN: Allow 1 test request to feature store.
  If success → transition to CLOSED
  If failure → transition to OPEN, wait longer (exponential backoff)

Fallback Models

When the primary model is unavailable (GPU failure, model corruption, timeout), serve a fallback.

Fallback TierDescriptionLatencyAccuracy
PrimaryLarge ensemble or deep model100msBest
Fallback 1Smaller distilled model (same architecture)25msGood
Fallback 2Rule-based or heuristic (e.g., average prediction)5msModerate
Fallback 3Default safe response (e.g., "approve with manual review")0msConservative
# Fallback chain logic
def predict(request):
    try:
        return primary_model.predict(request)  # 100ms
    except ModelError:
        try:
            return fallback_model.predict(request)  # 25ms
        except ModelError:
            try:
                return rule_based_predict(request)  # 5ms
            except:
                return DEFAULT_RESPONSE  # safe default

Graceful Degradation

When parts of the system fail, degrade features rather than failing entirely:

Exercise: Design the fault tolerance architecture for an AI-powered medical triage system that recommends urgency levels for emergency room patients. The system uses: a large LLM (GPU, 2s latency, best accuracy), a smaller BERT model (CPU, 200ms), and a rule-based system (instant). Describe the fallback chain, circuit breaker thresholds, what happens if the LLM is slow, and how you ensure the system never returns a "less urgent" recommendation than warranted.