Writing a retry decorator with exponential backoff in Python

Backend Live Coding November 13, 2026 python

What the interviewer looks for: functools.wraps, retrying only on specific exceptions (not all of them), re-raising on the last attempt, and jitter so that not all clients hit at the same time.

python
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
# ======================================================================
# Q: Write a decorator that retries with exponential backoff.
#
# What the interviewer looks for: functools.wraps, retrying only on specific
# exceptions (not all of them), re-raising on the last attempt, and jitter so
# that not all clients hit at the same time.
# ======================================================================

import functools, random, time

def retry(exceptions, tries=3, base_delay=0.5):
    def decorator(func):
        @functools.wraps(func)            # keeps __name__, __doc__
        def wrapper(*args, **kwargs):
            for attempt in range(1, tries + 1):
                try:
                    return func(*args, **kwargs)
                except exceptions:
                    if attempt == tries:
                        raise
                    time.sleep(base_delay * 2 ** (attempt - 1) + random.uniform(0, 0.1))
        return wrapper
    return decorator

@retry((ConnectionError, TimeoutError), tries=5)
def fetch_erp_prices(): ...