backoff
Python function decorators that retry calls on exceptions or bad return values, with exponential, fibonacci, or constant backoff and jitter.
Repository Health
Technical Analysis
backoff is a small, focused Python library that provides function decorators for retrying unreliable operations. Rather than hand-rolling retry loops around network calls or polling logic, you wrap a function with @backoff.on_exception to retry when a specific exception is raised, or @backoff.on_predicate to retry until a return value satisfies a condition. Both decorators accept a wait generator (expo, fibo, constant, decay, or runtime) that controls the pacing between attempts, plus give-up conditions like max_tries and max_time.
The library supports both synchronous functions and asyncio coroutines with an identical interface, dispatching internally based on whether the decorated target is a coroutine function. Jitter functions (full_jitter, random_jitter) can be layered on top of any wait generator to avoid thundering-herd collisions across concurrent clients, and event handler hooks (on_success, on_backoff, on_giveup) let callers wire in custom logging or metrics without touching the core retry logic.
What You Get
on_exceptiondecorator to retry a function when a specified exception (or tuple of exceptions) is raisedon_predicatedecorator to retry until the function’s return value satisfies a condition, defaulting to a falsy check- Wait generators —
expo,fibo,constant,decay, andruntime— for exponential, fibonacci, constant-interval, decay, and response-driven pacing full_jitterandrandom_jitterfunctions to randomize wait times and avoid retry collisions across clients- Native support for both synchronous functions and asyncio coroutines with the same decorator API
- Give-up controls via
max_tries,max_time, and a customgiveuppredicate function, plusraise_on_giveupto suppress the final exception
Common Use Cases
- Retrying HTTP requests to flaky or rate-limited external APIs with exponential backoff
- Polling a queue or resource for externally generated content using fibonacci or constant-interval backoff
- Respecting a
Retry-Afterresponse header via theruntimewait generator - Adding retry/backoff behavior to async I/O calls in asyncio-based services without separate sync/async code paths
- Emitting structured logs or metrics on each backoff/giveup event via
on_backoffandon_giveuphandlers
Under The Hood
Architecture
The library is organized as small, single-purpose modules under backoff/: _decorator.py exposes the public on_exception/on_predicate decorators, which configure logging and handler lists then dispatch to either _sync.py or _async.py based on asyncio.iscoroutinefunction(target) — the same decorator API transparently drives two different retry-loop implementations. Shared plumbing (_maybe_call, _init_wait_gen, _next_wait, default log handlers) lives in _common.py so both retry loops stay in sync. Wait pacing is fully decoupled from retry control flow: _wait_gen.py defines each strategy as a plain Python generator advanced with .send(), so on_exception/on_predicate never need to know which strategy is active. This separation means the core abstraction to change if extending the library is the wait-generator protocol (a generator that yields on send(value)), not the retry loops themselves.
Tech Stack
Pure Python with no runtime dependencies beyond the standard library (asyncio, logging, functools, itertools, math, datetime). Targets Python 3.7+ per pyproject.toml, built with Poetry (poetry-core backend). Type hints are enforced via mypy and a dedicated _typing.py module defines internal type aliases (_CallableT, _Predicate, _WaitGenerator, etc.). Dev tooling is flake8 for linting, pytest with pytest-asyncio and pytest-cov for testing, and requests/responses are used only in the test suite for HTTP-retry examples, not as a library dependency.
Code Quality
The test suite is extensive relative to the library’s size — test_backoff.py and test_backoff_async.py alone total over 1,600 lines covering sync and async retry paths in parallel, with additional focused suites for jitter, wait generators, and static typing (test_typing.py exercises the type stubs directly). The Makefile’s check target chains flake8, mypy --show-error-codes, and pytest, so linting and type-checking are treated as first-class alongside tests, though a GitHub Actions CI workflow is limited to CodeQL scanning rather than running this full check suite on every push. Naming and error handling are consistent throughout: internal helpers are underscore-prefixed, public decorators validate and normalize handler arguments via _config_handlers before entering the retry loop.
API Design
The two-decorator surface (on_exception, on_predicate) covers the overwhelming majority of retry scenarios with minimal boilerplate — a single decorator line with a wait generator and exception/predicate argument is enough to add production-grade retry behavior. Keyword-only arguments after the wait generator keep call sites readable, and accepting callables for max_tries/max_time allows runtime-evaluated configuration without extra ceremony. The identical API for sync and async code (the same @backoff.on_exception(backoff.expo, ...) line works on both) removes a common source of duplicated logic in codebases that mix sync and async call sites.
Used by 10 apps in this directory
Agno
Devops · AI Development · Automation
Build, run, and manage agent platforms with a full production stack — SDK, runtime, and control plane included.
Airbyte
Developer Tools · Data Engineering
Open-source ELT platform with 600+ connectors for moving data from any source to warehouses, lakes, and AI agents.
argilla
AI Development · Data Engineering
Collaborate on high-quality AI training data with a self-hosted annotation platform built for LLMs, NLP, and multimodal models.
Flagsmith
Developer Tools · Devops · Ab Testing Experimentation
Open-source feature flagging, remote config, and A/B/multivariate testing platform for web, mobile, and server-side apps — self-host or use the hosted SaaS.
GPT Researcher
Productivity · AI Assistants
The pioneering open-source autonomous AI agent that conducts deep, multi-source research and produces citation-backed reports exceeding 2,000 words — faster and more reliably than any human researcher.
Helicone
Monitoring · AI Development · Analytics
An open-source AI gateway and LLM observability platform that routes requests to 100+ models while logging cost, latency, and full traces for every call.
knowhere
AI Development · Developer Tools
Transform messy, unstructured documents into persistent, navigable memory that AI agents can actually use.
LiteLLM
AI Development · Developer Tools
Open source AI gateway and Python SDK that gives you one OpenAI-compatible interface to call 100+ LLM providers, with built-in routing, cost tracking, guardrails, and virtual keys.
Redash
Analytics · Data Engineering
Redash lets anyone connect to 35+ SQL and NoSQL data sources, write a query in the browser, and turn the result into a shared dashboard — no separate BI suite required.