Command Palette

Search for a command to run...

PHASE 11Intermediate ~7 min· topic 8 of 15

Topic 11.8

Circuit Breaker

In one line

When a dependency is failing, stop calling it — fail fast and let it recover. The Resilience4j pattern.

0/15 · 0%

Think of it like this

An electrical fuse in your house. If an appliance draws too much current, the fuse trips and cuts power immediately, preventing a fire — instead of letting the fault spread and burn down the whole house.

Key ideas

  1. 01

    Three states: CLOSED (calls flow), OPEN (calls fail instantly), HALF-OPEN (trial requests test recovery).

  2. 02

    Metrics drive transitions: failure rate threshold over a sliding window → OPEN; HALF-OPEN after a delay → CLOSED on success.

  3. 03

    Why: a dead dependency without a breaker → every caller waits on timeouts → threads pile → your OWN service dies (cascade).

  4. 04

    Fallbacks: return degraded data (cache, stub) when OPEN instead of failing the caller.

  5. 05

    Distinct from retries: retry adds attempts; breaker removes attempts while the dependency heals.

  6. 06

    Interview: 'circuit breaker on every downstream call — fail fast with a degraded response, trial-mode after 30s'.

Java / Spring map

  • →

    Resilience4j: @CircuitBreaker(name="orderSvc", fallbackMethod="degraded"); configure failureRateThreshold + waitDurationInOpenState.

Code & diagrams

circuit breaker statesdiagram
Rendering diagram…
Resilience4jConfig.javajava

The breaker config that turns dependency failure into graceful degradation.

@Bean
public CircuitBreaker orderServiceBreaker() {
  return CircuitBreaker.of("orderSvc", CircuitBreakerConfig.custom()
    .failureRateThreshold(50)              // >50% failures in window
    .slidingWindowSize(20)                 // …over the last 20 calls
    .waitDurationInOpenState(Duration.ofSeconds(30))  // trial after 30s
    .permittedNumberOfCallsInHalfOpenState(5)
    .build());
}

// usage with fallback:
@CircuitBreaker(name = "orderSvc", fallbackMethod = "bestEffort")
public OrderDetails getOrder(String id) {
  return client.getOrder(id);              // may throw / be slow
}

public OrderDetails bestEffort(String id, Throwable t) {
  return OrderDetails.fromCache(id);       // degrade, don't die
}

Explain without notes

01

Show the cascade: 30 services all calling a dead delivery service without breakers — what actually happens to threads?

Practice

01

Choose breaker thresholds (failure rate, window, trial period) for a 200ms-sla dependency.

Trade-offs

  • ↔

    Breakers trade 'probably-working' degradation for guaranteed fast failure; tune the open-state window to the dependency's recovery time.

Run it in production

Completion checklist

  • I put a breaker + fallback on every external call and can justify the thresholds.

Back to phase