DEV Community

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:

Comments

No comments yet. Start the discussion.