Category: python
What is the Circuit Breaker Pattern?
Published on 22 Aug 2026
Explanation
The Circuit Breaker pattern protects a microservice from repeatedly calling another service that is failing or unavailable. Instead of continuously sending requests to an unhealthy service, the circuit breaker temporarily stops requests and returns a fallback response. It normally has three states: CLOSED, OPEN, and HALF_OPEN. CLOSED allows requests normally. OPEN blocks requests after repeated failures. HALF_OPEN allows a limited test request to check whether the service has recovered.
Code:
from enum import Enum
class CircuitState(Enum):
CLOSED = 'CLOSED'
OPEN = 'OPEN'
HALF_OPEN = 'HALF_OPEN'
state = CircuitState.CLOSED
print('Current State:', state.value)
Explanation
A circuit breaker works through three main states. In the CLOSED state, requests are sent to the downstream service and failures are counted. When failures reach a configured threshold, the circuit changes to OPEN. While OPEN, requests are blocked immediately instead of calling the failing service. After a recovery period, the circuit changes to HALF_OPEN. A successful test request changes the circuit back to CLOSED, while another failure changes it back to OPEN.
Code:
class CircuitBreaker:
def __init__(self, failure_threshold=3):
self.failure_threshold = failure_threshold
self.failure_count = 0
self.state = 'CLOSED'
def record_success(self):
self.failure_count = 0
self.state = 'CLOSED'
def record_failure(self):
self.failure_count += 1
if self.failure_count >= self.failure_threshold:
self.state = 'OPEN'
breaker = CircuitBreaker(failure_threshold=3)
breaker.record_failure()
breaker.record_failure()
breaker.record_failure()
print('Circuit State:', breaker.state)
Explanation
A basic circuit breaker can be implemented using a failure counter and a state. Each failed request increases the failure count. When the configured threshold is reached, the circuit opens. Once the circuit is open, further requests are rejected without calling the downstream service. This protects the calling service from wasting resources on repeated calls to an unavailable dependency.
Code:
class CircuitBreaker:
def __init__(self, failure_threshold=3):
self.failure_threshold = failure_threshold
self.failure_count = 0
self.state = 'CLOSED'
def call(self, function, *args, **kwargs):
if self.state == 'OPEN':
raise Exception('Circuit is OPEN')
try:
result = function(*args, **kwargs)
self.failure_count = 0
return result
except Exception:
self.failure_count += 1
if self.failure_count >= self.failure_threshold:
self.state = 'OPEN'
raise
def payment_service():
raise Exception('Payment Service unavailable')
breaker = CircuitBreaker(failure_threshold=3)
for i in range(5):
try:
breaker.call(payment_service)
except Exception as error:
print('Request failed:', error)
print('Circuit:', breaker.state)
Explanation
In a Python microservices application, a circuit breaker can protect a FastAPI service when it communicates with another service using HTTPX. If the downstream service repeatedly times out or returns server errors, the circuit can open and prevent additional requests. The API can return a 503 response or a fallback result while the downstream service recovers. A production implementation should also include a recovery timeout, HALF_OPEN state, failure metrics, logging, and carefully selected retry policies.
Code:
import httpx
from fastapi import FastAPI, HTTPException
app = FastAPI()
failure_count = 0
FAILURE_THRESHOLD = 3
circuit_open = False
@app.get('/payment/{order_id}')
async def process_payment(order_id: int):
global failure_count, circuit_open
if circuit_open:
raise HTTPException(
status_code=503,
detail='Payment Service temporarily unavailable'
)
try:
async with httpx.AsyncClient() as client:
response = await client.post(
f'http://localhost:8002/payments/{order_id}',
timeout=3.0
)
response.raise_for_status()
failure_count = 0
return response.json()
except (httpx.TimeoutException, httpx.RequestError):
failure_count += 1
if failure_count >= FAILURE_THRESHOLD:
circuit_open = True
raise HTTPException(
status_code=503,
detail='Payment Service unavailable'
)
Explanation
Circuit breakers are commonly combined with timeouts and retries to create a resilient microservice. A timeout prevents a request from waiting indefinitely, while a limited retry can recover from a temporary network failure. If failures continue, the circuit opens and blocks further calls. After a configured recovery period, the circuit moves to HALF_OPEN and allows a test request. If the test succeeds, the circuit closes and normal traffic resumes. This combination helps prevent cascading failures across microservices.
Code:
import time
class CircuitBreaker:
def __init__(self, threshold=3, recovery_time=10):
self.threshold = threshold
self.recovery_time = recovery_time
self.failure_count = 0
self.last_failure = None
self.state = 'CLOSED'
def allow_request(self):
if self.state == 'CLOSED':
return True
if self.state == 'OPEN':
if time.time() - self.last_failure >= self.recovery_time:
self.state = 'HALF_OPEN'
return True
return False
return True
def success(self):
self.failure_count = 0
self.state = 'CLOSED'
def failure(self):
self.failure_count += 1
self.last_failure = time.time()
if self.failure_count >= self.threshold:
self.state = 'OPEN'
breaker = CircuitBreaker(threshold=3, recovery_time=10)
print('Initial State:', breaker.state)
breaker.failure()
breaker.failure()
breaker.failure()
print('After Failures:', breaker.state)
# After recovery period, the next request
# can move the circuit to HALF_OPEN.
# A successful request should call breaker.success().