Tenacity (retry with exponential backoff + jitter) handles transient errors. Circuit breaker (closed -> open -> half-open) handles sustained outages by short-circuiting before they pile up. Use both: tenacity in the inner loop, breaker in the outer. The breaker decides whether to retry at all.
Tenacity: retry 3x, wait_exponential_jitter (1, 2, 4 sec with ±30%).
Breaker: trip after 5 failures in 60 sec; cool-down 30 sec; half-open trial.
Pattern: if breaker.closed: try with tenacity; else: return cached or 503.
request -> breaker (closed/open/half-open)
if closed: tenacity.retry(call) -> success/fail
if open: 503 fast
Tenacity is “try harder”; circuit breaker is “stop trying”. You need both.