Home/Learn/Microservices/Resilience4j Circuit Breaker

Resilience4j Circuit Breaker

Intermediate
Resilience

Resilience4j is a lightweight fault-tolerance library providing CircuitBreaker, RateLimiter, Retry, Bulkhead, and TimeLimiter decorators for functional or reactive code.

Overview

Resilience4j is the de-facto standard fault-tolerance library for Spring Boot microservices, replacing the deprecated Hystrix. It provides six decorators: **CircuitBreaker** (stop calling a failing service), **Retry** (retry with backoff), **RateLimiter** (throttle calls per time window), **Bulkhead** (limit concurrent calls), **TimeLimiter** (enforce a timeout on async calls), and **Cache** (memoize results). All decorators are composable and work with `CompletableFuture`, reactive types, and plain functions. The **CircuitBreaker** uses a sliding window (count-based or time-based) to compute failure rates. When the rate exceeds a threshold, the circuit opens and subsequent calls immediately throw a `CallNotPermittedException`, giving the downstream service time to recover.

Circuit Breaker: States and Configuration

The CircuitBreaker has three states: **CLOSED** (normal, calls pass through), **OPEN** (failing, calls blocked for `waitDurationInOpenState`), **HALF_OPEN** (probe — a limited number of calls are allowed; if they succeed, circuit closes; if they fail, it reopens). Configuration is set in `application.yml` under `resilience4j.circuitbreaker.instances.<name>`.

Spring Boot — resilience4j CircuitBreaker config
# application.yml
resilience4j:
  circuitbreaker:
    instances:
      payment-service:
        slidingWindowType: COUNT_BASED     # or TIME_BASED
        slidingWindowSize: 10              # last 10 calls
        failureRateThreshold: 50           # open if ≥50% fail
        slowCallRateThreshold: 80          # open if ≥80% are slow
        slowCallDurationThreshold: 2000ms
        waitDurationInOpenState: 10s       # stay open 10s before HALF_OPEN
        permittedNumberOfCallsInHalfOpenState: 3
        minimumNumberOfCalls: 5            # need at least 5 calls before evaluating

# Spring Boot Actuator exposes circuit breaker state:
# GET /actuator/circuitbreakers
# GET /actuator/circuitbreakerevents

@CircuitBreaker on Service Methods

Annotate service methods with `@CircuitBreaker(name = "payment-service", fallbackMethod = "fallback")`. The fallback method must have the same signature plus a `Throwable` parameter. Combine with `@Retry` on the same method — decorators are applied in a specific order (Retry → CircuitBreaker → RateLimiter → TimeLimiter → Bulkhead).

Spring Boot — @CircuitBreaker with fallback
@Service
public class OrderService {

    @CircuitBreaker(name = "payment-service", fallbackMethod = "paymentFallback")
    @Retry(name = "payment-service")
    @TimeLimiter(name = "payment-service")
    public CompletableFuture<PaymentResult> processPayment(Order order) {
        return CompletableFuture.supplyAsync(
            () -> paymentClient.charge(order.getId(), order.getAmount())
        );
    }

    // Fallback — same return type + Throwable
    public CompletableFuture<PaymentResult> paymentFallback(
            Order order, Throwable ex) {
        log.warn("Payment service unavailable: {}", ex.getMessage());
        return CompletableFuture.completedFuture(
            PaymentResult.deferred(order.getId())  // queue for later retry
        );
    }
}

Retry and RateLimiter Configuration

`@Retry` retries on specific exceptions with exponential backoff and jitter. `@RateLimiter` limits calls per time window — callers block up to `timeoutDuration` waiting for a permit; after that, `RequestNotPermitted` is thrown. Both are configured in `application.yml` alongside the circuit breaker.

Spring Boot — Retry and RateLimiter config
# application.yml
resilience4j:
  retry:
    instances:
      payment-service:
        maxAttempts: 3
        waitDuration: 500ms
        enableExponentialBackoff: true
        exponentialBackoffMultiplier: 2.0
        randomizedWaitFactor: 0.5           # jitter to avoid thundering herd
        retryExceptions:
          - java.net.ConnectException
          - feign.RetryableException
        ignoreExceptions:
          - com.example.BusinessException   # don't retry business errors

  ratelimiter:
    instances:
      payment-service:
        limitForPeriod: 100                 # 100 calls per period
        limitRefreshPeriod: 1s
        timeoutDuration: 500ms             # wait up to 500ms for a permit

Key Points to Remember

  • 1CircuitBreaker has three states: CLOSED (normal), OPEN (blocked), HALF_OPEN (probing)
  • 2failureRateThreshold triggers OPEN; waitDurationInOpenState controls recovery pause
  • 3Fallback method must have same signature as the decorated method plus a Throwable parameter
  • 4Decorator order: Retry → CircuitBreaker → RateLimiter → TimeLimiter → Bulkhead
  • 5@Retry uses exponential backoff + jitter to avoid thundering herd on recovery
  • 6Expose circuit breaker state via Spring Actuator /actuator/circuitbreakers endpoint

Interview Questions

Sign in to ask Aria
1

Explain the three states of a circuit breaker and the transitions between them.

EasyNetflix
2

What is the difference between a count-based and time-based sliding window in Resilience4j?

MediumThoughtWorks
3

Why is it important to add jitter to retry backoff times?

MediumAmazon
4

What is the order in which Resilience4j decorators are applied?

HardPivotal
5

How does the Bulkhead pattern differ from the Circuit Breaker pattern?

MediumUber

Ask Aria about Resilience4j Circuit Breaker

Your personal AI tutor — ask anything about this concept

Revision Status

Personal Notes

Sign in to save personal notes for this topic.

Discussion

Sign in to join the discussion.

Loading discussion…