DEV Community

Cover image for How the Circuit Breaker Pattern Prevents Cascading Failures in Microservices
Preeti Sharma
Preeti Sharma

Posted on

How the Circuit Breaker Pattern Prevents Cascading Failures in Microservices

Modern microservice architectures improve scalability and team autonomy, but they also introduce a new challenge: service dependency failures.

If one service becomes slow or unavailable, it can easily cascade across the system, bringing down multiple services.

This is where the Circuit Breaker Pattern becomes extremely important.

In this article we will cover:

  • The cascading failure problem
  • How circuit breakers solve it
  • Circuit breaker states
  • A working example using Resilience4j
  • Best practices when using circuit breakers

The Cascading Failure Problem

Imagine a simple microservice system:

Client → Order Service → Payment Service → Database
Enter fullscreen mode Exit fullscreen mode

Now assume the Payment Service becomes slow or unavailable.

What happens?

  1. Order service keeps sending requests.
  2. Requests start waiting.
  3. Threads become blocked.
  4. System resources get exhausted.
  5. Eventually the Order Service also crashes.

This is called a cascading failure.

A single failure spreads across services.


The Circuit Breaker Concept

The concept is inspired by electrical circuit breakers.

When electrical current becomes dangerous, the circuit breaker cuts the flow to prevent damage.

Similarly in microservices, a circuit breaker:

  • monitors failures
  • stops sending requests temporarily
  • allows the system to recover

Instead of continuously calling a failing service, we fail fast.


Circuit Breaker States

A circuit breaker typically has three states.

1️⃣ Closed State

Client → Order Service → Payment Service
Enter fullscreen mode Exit fullscreen mode
  • Requests flow normally
  • Failures are monitored
  • If failures exceed threshold → state changes

2️⃣ Open State

Client → Order Service ✖ Payment Service
Enter fullscreen mode Exit fullscreen mode
  • Calls are blocked immediately.
  • No request is sent to failing service.
  • System return a fallback response.

3️⃣ Half-Open State

Client → Order Service → Payment Service (limited test requests)
Enter fullscreen mode Exit fullscreen mode
  • Only a few requests allowed.
  • If they succeed → circuit closes.
  • If they fail → circuit opens again

Circuit Breaker Flow

Closed → Failures detected → Open
Open → Cooldown period → Half-Open
Half-Open → Success → Closed
Half-Open → Failure → Open
Enter fullscreen mode Exit fullscreen mode

Implementing Circuit Breaker using Resilience4j

One of the most popular circuit breaker libraries in Java is Resilience4j.
It works very well with Spring Boot.


Add Dependency

<dependency>
 <groupId>io.github.resilience4j</groupId>
 <artifactId>resilience4j-spring-boot3</artifactId>
</dependency>
Enter fullscreen mode Exit fullscreen mode

Configure Circuit Breaker

application.yml

resilience4j:
  circuitbreaker:
    instances:
      paymentService:
        registerHealthIndicator: true
        slidingWindowSize: 10
        minimumNumberOfCalls: 5
        failureRateThreshold: 50
        waitDurationInOpenState: 10s
Enter fullscreen mode Exit fullscreen mode

Explanation:

  • slidingWindowSize → number of calls monitored
  • failureRateThreshold → percentage to trigger breaker
  • waitDurationInOpenState → time before retry

Applying Circuit Breaker to a Service

Example: calling a Payment Service.

@Service
public class PaymentClient {

    @CircuitBreaker(name = "paymentService", fallbackMethod = "fallbackPayment")
    public String processPayment() {

        // call external payment service
        return restTemplate.getForObject(
            "http://payment-service/pay",
            String.class
        );
    }

    public String fallbackPayment(Throwable ex) {
        return "Payment service unavailable. Please try later.";
    }
}
Enter fullscreen mode Exit fullscreen mode

What happens here:

  1. Calls go normally.
  2. If failure rate exceeds threshold → circuit opens.
  3. All calls go directly to fallback method.

What a Fallback Response Looks Like

Fallback responses prevent system crashes.

{
 "status": "FAILED",
 "message": "Payment service temporarily unavailable"
}
Enter fullscreen mode Exit fullscreen mode

Instead of crashing, the system degrades gracefully.


When Should You Use Circuit Breakers?

Circuit breakers are useful when:

  • calling external APIs.
  • calling slow microservices.
  • interacting with unreliable networks.

Typical examples:

Order Service → Payment Service
Checkout Service → Inventory Service
API Gateway → User Service
Enter fullscreen mode Exit fullscreen mode

When NOT to Use Circuit Breakers

Avoid using circuit breakers for:

  • database calls inside the same service
  • very fast local operations
  • in-memory calls

Circuit breakers are best suited for remote network calls.


Best Practices

✔ Always define fallback responses
✔ Monitor breaker metrics
✔ Combine with retry mechanism
✔ Use timeouts with circuit breakers


Final Thoughts

Microservices improve scalability and flexibility, but they also introduce reliability challenges when services depend on each other. A failure in one service can quickly propagate and lead to cascading failures across the system.

The Circuit Breaker Pattern helps prevent this by stopping repeated calls to failing services and allowing systems to fail fast with fallback responses. Tools like Resilience4j make it easy to implement this pattern in Spring Boot applications.

In the next article, we’ll explore building production-grade resilience using Resilience4j, including retries, bulkheads, and other advanced patterns.

Stay tuned for the next part of this series 🚀

Top comments (0)