interlock¶
A modern circuit breaker for Python — sync and async in a single class, sliding-window rate and slow-call detection, a type-safe API, and transparent integrations at the transport level.
Why interlock¶
- Sync and async, one class. A single
CircuitBreakerdetects coroutine callables and dispatches to the right path — noSync*/Async*twins. - Sliding windows by rate. Both count-based and time-based windows, not the naive consecutive-failure counter found elsewhere in the ecosystem.
- Slow-call detection. Treat calls slower than a threshold as failures — not available in any other Python circuit breaker.
- Type-safe.
ParamSpec+TypeVardecorators that preserve signatures; shipspy.typedand passes mypy in strict mode. - Zero-dependency core. Standard library only; everything external lives in optional extras.
- Safe production rollout. Start in
METRICS_ONLYto observe real traffic without rejecting it, then enable enforcement with tuned thresholds. - Thread-safe, and checked. One
threading.Lockguards the critical sections; your callable runs outside it. CI drives a single breaker from many threads at once — on free-threaded CPython (3.14t) as well as the GIL builds — so the guarantee is verified, not merely asserted. - Distributed state (optional). Coordinate tripping and recovery probing across instances through Redis/Valkey, with graceful degradation to local state — see the Redis integration.
Choosing between libraries? See the honest comparison with pybreaker, circuitbreaker, aiobreaker and purgatory.
Installation¶
At a glance¶
from interlock import CircuitBreaker, CircuitOpenError
breaker = CircuitBreaker(name='payments')
@breaker
def charge(amount: int) -> str:
return gateway.charge(amount)
try:
charge(100)
except CircuitOpenError as exc:
... # rejected fast: the dependency is unhealthy; retry after exc.retry_after
The same instance protects async callables, works as a (sync and async) context
manager, and can be called directly via breaker.call(fn, ...) — start with
Getting started.
AI coding agents¶
The repository ships an Agent Skill that walks a coding agent through adding interlock to a codebase: an inventory of outbound calls, the integration to use for each, threshold sizing, a shadow-mode rollout, tests driven by a fake clock, and the migration from pybreaker or circuitbreaker. It installs into Claude Code, Cursor, Codex, GitHub Copilot, Gemini CLI and the other agents that read the open skills format:
Then ask the agent to add circuit breakers to a service. Agents that read documentation directly can use llms.txt, the fully inlined llms-full.txt or Context7.
Status¶
interlock shipped a polished core first (state machine, windows, sync/async,
slow-call detection), then grew deliberately: v1.1 added timeouts, proactive
OPEN → HALF_OPEN and FastAPI; v1.2 added coordinated distributed state over
Redis; v1.3 added the integrations wave — aiohttp, requests and
retry × breaker composition via tenacity; v2.0 composes
it all declaratively in the resilience pipeline —
timeout, bulkhead, breaker, retry and fallback around the same standalone
breaker.