backon — The Modern Python Retry Library You've Been Waiting For
If you've written Python code that talks to external APIs, databases, or network services, you've needed retry logic. The Python ecosystem has several options:
- backoff (2.7k ★) — The most popular, but now archived and no longer maintained
- tenacity — In maintenance mode, limited features
- retrying — Unmaintained since 2021
Enter backon, the modern evolution of backoff.
pip install backon
Why backon?
backon is a zero-dependency Python library that provides four APIs for retry: decorator, functional, context manager, and callable. It works with both sync and async code out of the box.
1. Retry on Exception (Decorator)
import backon
@backon.on_exception(backon.expo, ValueError, max_tries=3)
def fetch_data():
return api.call()
2. Retry on Predicate
@backon.on_predicate(backon.constant, max_tries=5, interval=0.5)
def poll_status():
return check_ready()
3. Functional API
result = backon.retry(
fetch_data,
backon.expo,
exception=ValueError,
max_tries=3,
)
4. Context Manager
with backon.Retrying(backon.expo, exception=ValueError, max_tries=3) as r:
result = r.call(fetch_data)
Async variant:
async with backon.Retrying(backon.constant, exception=ValueError, max_tries=3, interval=0.5) as r:
result = await r.async_call(fetch_data)
Beyond Basic Retry
backon includes features you won't find in other Python retry libraries:
Circuit Breaker
Three-state circuit breaker (CLOSED/OPEN/HALF_OPEN) with automatic recovery:
from backon._circuit_breaker import BreakerRetrying, CircuitBreaker
breaker = BreakerRetrying(
backon.expo, max_tries=3,
breaker=CircuitBreaker(failure_threshold=5, recovery_timeout=60.0),
)
result = breaker.call(fetch)
Hedging
Run multiple retry attempts concurrently, return the first success:
from backon._hedging import hedge
result = hedge(fetch, backon.expo, max_hedge=3)
Prometheus / OpenTelemetry Metrics
Optional metrics with zero hard dependencies:
from backon._instrumentation import PrometheusMetrics, set_metrics_collector
set_metrics_collector(PrometheusMetrics())
Testing Utilities
Skip retry in tests, limit retries, or assert retry behavior:
from backon._testing import disable_retries, assert_retried
with disable_retries():
result = fetch() # no retry
assert_retried(fetch, expected_tries=3)
Full Feature List
- Zero dependencies — pure Python, stdlib only
- Four APIs — decorator, functional, context manager, callable
- Async native — same API works for async def
- Full type hints — validated with mypy, strict mode compatible
- Global toggle — backon.disable() / backon.enable() for testing
- Multiple wait strategies — exponential, constant, Fibonacci, decay, runtime
- Jitter — full jitter, random jitter, or none
- Rich callbacks — on_attempt, on_backoff, on_success, on_giveup
- Circuit breaker — CLOSED/OPEN/HALF_OPEN with automatic recovery
- Hedging — concurrent retry, first-success-wins
- Prometheus / OpenTelemetry metrics
- Testing module — disable_retries(), limit_retries(), remove_backoff()
- Trio support
- Operator overloading — compose stops with | / &, waits with +
- Iterator API — for attempt in Retrying(...):
Migrating from backoff
It's a near-drop-in replacement:
- import backoff
+ import backon
- @backoff.on_exception(backoff.expo, ValueError, max_tries=3)
+ @backon.on_exception(backon.expo, ValueError, max_tries=3)
Quick Install
pip install backon
Requires Python 3.10+.
Links:
Top comments (0)