Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/danielfm/pybreaker/llms.txt

Use this file to discover all available pages before exploring further.

By default, PyBreaker stores circuit breaker state in local memory via CircuitMemoryStorage. This means every process or application instance maintains its own independent circuit state — one instance can have an open circuit while another runs normally. For multi-process or multi-instance deployments (e.g., multiple web workers, containerised services, or horizontally scaled APIs), use CircuitRedisStorage to share state across all instances so they act as a single coordinated circuit breaker.

Installation

pip install pybreaker redis

Basic Redis Setup

Create a Redis connection and pass a CircuitRedisStorage instance as the state_storage argument when constructing your circuit breaker.
import pybreaker
import redis

redis_conn = redis.StrictRedis()
db_breaker = pybreaker.CircuitBreaker(
    fail_max=5,
    reset_timeout=60,
    state_storage=pybreaker.CircuitRedisStorage(
        pybreaker.STATE_CLOSED,  # Initial state
        redis_conn
    )
)
The first argument to CircuitRedisStorage is the initial state — the state written to Redis if no key exists yet. Use pybreaker.STATE_CLOSED to start the circuit closed (normal operation).
Do NOT initialize the Redis connection with decode_responses=True. This forces ASCII string objects from Redis and will cause AttributeError: 'str' object has no attribute 'decode' in Python 3+. PyBreaker handles decoding internally and expects raw bytes back from Redis reads.

Using with Django Redis

If your project uses django-redis, you can obtain the configured Redis connection from Django’s cache backend and pass it directly to CircuitRedisStorage.
import pybreaker
from django_redis import get_redis_connection

db_breaker = pybreaker.CircuitBreaker(
    fail_max=5,
    reset_timeout=60,
    state_storage=pybreaker.CircuitRedisStorage(
        pybreaker.STATE_CLOSED,
        get_redis_connection('default')
    )
)
Ensure the default cache backend in settings.py is not configured with OPTIONS: {"CLIENT_CLASS": "...", "DECODE_RESPONSES": True} — see the warning above.

Multiple Breakers with Namespaces

When you have more than one circuit breaker sharing the same Redis connection, each breaker must be given a unique namespace. Without namespaces, all breakers write to the same Redis keys and will corrupt each other’s state.
import pybreaker
import redis

redis_conn = redis.StrictRedis()

# Each breaker gets a unique namespace to avoid key collisions
db_breaker = pybreaker.CircuitBreaker(
    fail_max=5,
    reset_timeout=60,
    state_storage=pybreaker.CircuitRedisStorage(
        pybreaker.STATE_CLOSED,
        redis_conn,
        namespace='db_service'
    )
)

api_breaker = pybreaker.CircuitBreaker(
    fail_max=3,
    reset_timeout=30,
    state_storage=pybreaker.CircuitRedisStorage(
        pybreaker.STATE_CLOSED,
        redis_conn,
        namespace='payment_api'
    )
)
With a namespace, all Redis keys for that breaker are prefixed as <namespace>:pybreaker:<key>. Without a namespace, keys are stored as pybreaker:<key>.

Fallback State

If Redis becomes unavailable (e.g., connection refused, timeout), CircuitRedisStorage falls back to a configurable default state rather than crashing. The fallback_circuit_state parameter controls this behaviour.
state_storage = pybreaker.CircuitRedisStorage(
    pybreaker.STATE_CLOSED,
    redis_conn,
    fallback_circuit_state=pybreaker.STATE_CLOSED  # Default: STATE_CLOSED
)
Setting fallback_circuit_state=pybreaker.STATE_CLOSED means that when Redis is unreachable, the circuit breaker will allow calls through (fail open). If you prefer to block calls when Redis is down, set fallback_circuit_state=pybreaker.STATE_OPEN.

Redis Cluster Mode

Standard Redis transactions (MULTI/EXEC) are not supported in Redis Cluster deployments when keys span multiple hash slots. Enable cluster_mode=True to use a non-transactional write path that is compatible with Redis Cluster.
state_storage = pybreaker.CircuitRedisStorage(
    pybreaker.STATE_CLOSED,
    redis_conn,
    cluster_mode=True  # Avoids MULTI/EXEC transactions incompatible with cluster
)

Redis Keys

CircuitRedisStorage maintains four keys in Redis per circuit breaker instance. The key format is pybreaker:<key> when no namespace is set, or <namespace>:pybreaker:<key> when a namespace is provided.
KeyDescription
fail_counterCurrent consecutive failure count
success_counterCurrent consecutive success count (used in half-open state)
stateCurrent state string — one of closed, open, or half-open
opened_atUnix timestamp (integer) of when the circuit was last opened

Build docs developers (and LLMs) love