Hackforge Academy

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().

πŸš€ Learn Spring Boot with real-world projects

πŸ’‘ Build REST APIs step by step

🧠 Improve backend development skills

🎯 Get career-ready practical training

Join Our Free WhatsApp Community

Direct access to niche-specific mentors and peers on WhatsApp.

🐍

Python Community

Discuss Django, FastAPI, AI integration, and automation scripts with 15k+ developers.

Join Python Community
βš›οΈ

React Community

Master Next.js, Framer Motion, and State Management. Share your latest UI components.

Join React Community
β˜•

Java Community

Deep dives into Spring Boot, Microservices architecture, and high-performance backend ops.

Join Java Community