patternpythonMajorpending
Pattern: Retry with exponential backoff and jitter
Viewed 0 times
retryexponential-backoffjitterthundering-herdresilience
Problem
Fixed retry intervals cause thundering herd when many clients retry simultaneously after a service recovers.
Solution
Use exponential backoff with jitter:
import random, time
def retry_with_backoff(fn, max_retries=5, base_delay=1.0, max_delay=60.0):
for attempt in range(max_retries):
try:
return fn()
except (ConnectionError, TimeoutError) as e:
if attempt == max_retries - 1:
raise
# Exponential backoff with full jitter
delay = min(base_delay * (2 ** attempt), max_delay)
jittered = random.uniform(0, delay)
print(f'Attempt {attempt + 1} failed, retrying in {jittered:.1f}s')
time.sleep(jittered)
# Decorator version:
def retryable(max_retries=3, exceptions=(Exception,)):
def decorator(fn):
def wrapper(*args, **kwargs):
for attempt in range(max_retries):
try:
return fn(*args, **kwargs)
except exceptions:
if attempt == max_retries - 1:
raise
time.sleep(min(2 ** attempt + random.random(), 30))
return wrapper
return decorator
@retryable(max_retries=5, exceptions=(ConnectionError,))
def call_api():
return requests.get('https://api.example.com/data')
import random, time
def retry_with_backoff(fn, max_retries=5, base_delay=1.0, max_delay=60.0):
for attempt in range(max_retries):
try:
return fn()
except (ConnectionError, TimeoutError) as e:
if attempt == max_retries - 1:
raise
# Exponential backoff with full jitter
delay = min(base_delay * (2 ** attempt), max_delay)
jittered = random.uniform(0, delay)
print(f'Attempt {attempt + 1} failed, retrying in {jittered:.1f}s')
time.sleep(jittered)
# Decorator version:
def retryable(max_retries=3, exceptions=(Exception,)):
def decorator(fn):
def wrapper(*args, **kwargs):
for attempt in range(max_retries):
try:
return fn(*args, **kwargs)
except exceptions:
if attempt == max_retries - 1:
raise
time.sleep(min(2 ** attempt + random.random(), 30))
return wrapper
return decorator
@retryable(max_retries=5, exceptions=(ConnectionError,))
def call_api():
return requests.get('https://api.example.com/data')
Why
Jitter prevents synchronized retries (thundering herd). Exponential backoff gives the failing service time to recover.
Revisions (0)
No revisions yet.