Retry decorator with exponential backoff
Re-run a flaky function a limited number of times with growing delays, only for chosen exception types.
- Python
- GreenSnippets
- MIT
- Executed with Python 3.11
import functools
import time
def retry(attempts=3, delay=0.5, backoff=2.0, exceptions=(Exception,)):
def decorator(func):
@functools.wraps(func)
def wrapper(*args, **kwargs):
wait = delay
for attempt in range(1, attempts + 1):
try:
return func(*args, **kwargs)
except exceptions:
if attempt == attempts:
raise
time.sleep(wait)
wait *= backoff
return wrapper
return decoratorHow it works
A decorator keeps retry logic out of business code. Only the exceptions you list are retried; anything else propagates immediately. The last exception is re-raised once attempts run out, and functools.wraps preserves the wrapped function's name and docstring.
Retry only idempotent operations, and add jitter if many processes may retry together.
Related snippets
- PHP Tested
Retry a callable with exponential backoff in PHP
Re-run flaky operations with growing delays and jitter, only for chosen exception types.
- TypeScript Tested
Typed fetch helper that checks the response
A fetch wrapper that throws on HTTP errors and validates the JSON body with a type guard.
- JavaScript Tested
Verify a webhook signature in Node.js
Validate an HMAC-SHA256 webhook against the raw request body with a constant-time comparison and replay window.
- PHP Tested
Decode JSON safely in PHP
Parse JSON with exceptions on error and a depth limit, instead of silently getting null.

