Stage 4 · Provision
Resilience Patterns
Retry Strategies
Exponential backoff, jitter, retry budgets, and idempotency requirements for safe retries.
Why Retry?
Transient failures — network blips, momentary overload, connection resets — are common in distributed systems. Retrying the failed operation often succeeds. However, retries can amplify load and cause cascading failures if not implemented carefully.
Exponential Backoff
Exponential backoff increases the delay between retries exponentially: 1s, 2s, 4s, 8s, 16s. This gives the downstream service time to recover. Without backoff, retries hit the struggling service at the same rate, making recovery impossible.
import time
import random
def retry_with_backoff(func, max_retries=3, base_delay=1.0, max_delay=30.0):
for attempt in range(max_retries + 1):
try:
return func()
except (ConnectionError, TimeoutError) as e:
if attempt == max_retries:
raise
# Exponential backoff with jitter
delay = min(base_delay * (2 ** attempt), max_delay)
jitter = delay * random.uniform(0.5, 1.0) # 50-100% of delay
time.sleep(jitter)Jitter prevents all clients from retrying at the same time (thundering herd). The delay is randomized between 50-100% of the calculated backoff.
Adding Jitter
# Full jitter (recommended by AWS)
delay = random.uniform(0, min(cap, base * 2 ** attempt))
# Equal jitter
temp = min(cap, base * 2 ** attempt)
delay = temp / 2 + random.uniform(0, temp / 2)
# Decorrelated jitter
delay = min(cap, random.uniform(base, prev_delay * 3))Full jitter provides the best performance in most scenarios. It spreads retries across the maximum time window, reducing contention.
Retry Budgets
A retry budget limits the total number of retries per second. Without a budget, retries can double the load on a struggling service. A common budget: retries cannot exceed 10% of normal request volume.
retry_budget:
budget_percent:
value: 20.0 # Max 20% of requests can be retries
min_retry_concurrency: 3 # At least 3 concurrent retries allowedThe retry budget ensures that retries do not overwhelm the downstream service. Once the budget is exhausted, new requests fail immediately without retrying.
When NOT to Retry
- Non-idempotent operations — POST, DELETE, PUT without idempotency keys.
- 4xx errors (except 429) — Client errors are not transient.
- Business logic failures — Payment declined, insufficient inventory.
- Authentication failures — Retrying with the same credentials will fail.
Retrying a POST without an idempotency key creates duplicate records. Retrying a payment charges the customer twice. Only retry operations that are safe to repeat.
Retry Configuration
| Parameter | Recommendation | Why |
|---|---|---|
| Max retries | 3 | Diminishing returns after 3 |
| Base delay | 500ms-1s | Give service time to recover |
| Max delay | 30s | Don't wait forever |
| Jitter | Full jitter | Prevent thundering herd |
| Budget | 10-20% | Limit retry amplification |
429 (rate limited) means try again later. 503 (service unavailable) means try again soon. All other 4xx are client errors. 5xx may be retryable depending on the error type.
Mark this lesson complete to store local progress and unlock a cleaner resume path the next time you visit.