Chaturmind
LearnDSASystem DesignDevOpsEngineering GrowthBlog
Start learning
Chaturmind

Structured learning paths for engineers who want to go deep. Written by practitioners.

Learn

  • Java
  • DSA
  • System Design
  • Spring Boot
  • AI / ML
  • DevOps
  • Engineering Growth

Company

  • Blog
  • Contact

Legal

  • Privacy Policy
  • Terms of Service

© 2026 Chaturmind. All rights reserved.

Built for engineers who want to go deep.


← Spring Boot REST API Development

Spring Boot Basics

  • What is Spring Boot?
  • Dependency Injection
  • Building REST Controllers

Validation & Error Handling

  • Bean Validation with @Valid
  • Global Exception Handling

Spring Framework Internals

  • IoC Container Fundamentals
  • Bean Lifecycle In Detail
  • Component Scanning & Configuration
  • Auto-Configuration Mechanism
  • Spring AOP
  • @Transactional Deep Dive

Microservices Architecture

  • Monolith to Microservices Decomposition
  • API Gateway
  • Service Discovery
  • Inter-Service Communication Choices
  • Event-Driven Architecture Patterns
  • Messaging Technology Choices

Resilience Patterns

  • Configuration Management
  • Circuit Breaker Pattern
  • Retry & Backoff Strategies
  • Bulkhead & Rate Limiting
  • Timeout Strategy
  • Why Microservices Fail

Distributed Data & Consistency Patterns

  • Two-Phase Commit
  • Saga Pattern
  • Outbox Pattern
  • Eventual Consistency Design
  • CQRS Basics
  • CAP Theorem

Observability & Operations

  • Centralized Logging
  • Distributed Tracing
  • Metrics & Monitoring
  • Alerting Strategy
  • Health Checks

Payment Systems

  • Payment — Requirements
  • Payment — Core Flow
  • Payment — Idempotency Implementation
  • Payment — Failure Handling & Reconciliation
  • Payment — Security

Order Management System

  • OMS — Requirements
  • OMS — State Machine Design
Chaturmind
← Spring Boot REST API Development

Spring Boot Basics

  • What is Spring Boot?
  • Dependency Injection
  • Building REST Controllers

Validation & Error Handling

  • Bean Validation with @Valid
  • Global Exception Handling

Spring Framework Internals

  • IoC Container Fundamentals
  • Bean Lifecycle In Detail
  • Component Scanning & Configuration
  • Auto-Configuration Mechanism
  • Spring AOP
  • @Transactional Deep Dive

Microservices Architecture

  • Monolith to Microservices Decomposition
  • API Gateway
  • Service Discovery
  • Inter-Service Communication Choices
  • Event-Driven Architecture Patterns
  • Messaging Technology Choices

Resilience Patterns

  • Configuration Management
  • Circuit Breaker Pattern
  • Retry & Backoff Strategies
  • Bulkhead & Rate Limiting
  • Timeout Strategy
  • Why Microservices Fail

Distributed Data & Consistency Patterns

  • Two-Phase Commit
  • Saga Pattern
  • Outbox Pattern
  • Eventual Consistency Design
  • CQRS Basics
  • CAP Theorem

Observability & Operations

  • Centralized Logging
  • Distributed Tracing
  • Metrics & Monitoring
  • Alerting Strategy
  • Health Checks

Payment Systems

  • Payment — Requirements
  • Payment — Core Flow
  • Payment — Idempotency Implementation
  • Payment — Failure Handling & Reconciliation
  • Payment — Security

Order Management System

  • OMS — Requirements
  • OMS — State Machine Design
HomeLearnSpring BootSpring Boot REST API DevelopmentResilience Patterns
✓ FreeAdvanced· 9 min read

Circuit Breaker Pattern

The three-state machine in production via Resilience4j: failure-rate thresholds and sliding windows, fallback design, which failures should trip the breaker, and Resilience4j vs the deprecated Hystrix.

Published September 23, 2026


Circuit Breaker Pattern

Design a Circuit Breaker built this exact three-state machine from scratch. This lesson is the production version — Resilience4j — and the operational decisions around it.

The three states, as Resilience4j implements them

@CircuitBreaker(name = "paymentService", fallbackMethod = "fallbackCharge")
public ChargeResult chargeCard(ChargeRequest request) {
    return paymentClient.charge(request);
}

public ChargeResult fallbackCharge(ChargeRequest request, Exception ex) {
    return ChargeResult.pending("Payment service unavailable, queued for retry");
}

Closed (normal): calls pass through, failures are tracked. Open (fast-fail): calls are rejected immediately, routed straight to the fallback, without even attempting the real call — protecting a struggling dependency from additional load while it recovers. Half-open (trial): after a configured wait duration, a limited number of trial calls are let through to test recovery — matching the from-scratch implementation in Design a Circuit Breaker exactly.

Failure rate threshold and sliding window configuration

resilience4j:
  circuitbreaker:
    instances:
      paymentService:
        sliding-window-size: 20         # consider the last 20 calls
        failure-rate-threshold: 50      # trip if >= 50% of those 20 failed
        wait-duration-in-open-state: 30s
        permitted-number-of-calls-in-half-open-state: 5

This is the meaningful upgrade over a simple cumulative failure counter (as Design a Circuit Breaker's hand-rolled version used): a sliding window considers only the most recent N calls, so failures from an hour ago don't still count against a service that's been healthy since — an old failure eventually "ages out" of the window automatically, giving a much more accurate signal of current health than an ever-accumulating count that only resets on a full success.

Fallback method design

Three common fallback shapes, in rough order of preference when available: default value (return a safe, generic response — a recommendation service's fallback might be "no recommendations" rather than an error), cached value (return the last known-good result, even if slightly stale — appropriate when staleness beats absence), graceful degradation message (explicitly tell the caller this feature is temporarily unavailable, rather than either crashing or silently returning wrong-looking data). Choosing the wrong shape is a real failure mode itself — returning a default value that looks like a legitimate result (rather than being clearly marked as a fallback) can mislead calling code or users into trusting degraded data as if it were normal.

Which failures should trip the breaker

@CircuitBreaker(name = "paymentService")
// Resilience4j default: counts exceptions as failures, but this is configurable —
// record-exceptions / ignore-exceptions lets you exclude specific types

Worth tripping the breaker: 5xx server errors, timeouts — signals the dependency itself is unhealthy. Should NOT trip the breaker: 4xx client errors (a 400 Bad Request means the caller sent something wrong, not that the dependency is struggling) — counting client errors toward the failure threshold would trip the breaker due to caller mistakes, incorrectly treating a healthy-but-misused dependency as failing. This distinction — worth stating explicitly and unprompted — is exactly the kind of nuance that separates "knows the pattern exists" from "has actually operated one in production."

Monitoring breaker state transitions

circuitBreakerRegistry.circuitBreaker("paymentService").getEventPublisher()
    .onStateTransition(event -> log.warn("Circuit breaker state: {}", event));

A circuit breaker tripping to OPEN is itself a significant operational signal — it means a real dependency is failing badly enough to warrant fast-failing rather than attempting calls. Exposing state transitions to monitoring dashboards (see Metrics & Monitoring) means an OPEN breaker shows up as a visible, alertable event, not a silent internal detail only discoverable by noticing degraded functionality downstream.

Resilience4j vs Hystrix

Hystrix (Netflix's original circuit breaker library) is deprecated and no longer actively maintained — it used thread-pool isolation (a dedicated thread pool per protected call, adding real overhead per call and consuming meaningfully more resources). Resilience4j is lightweight and functional (composable decorators around a Supplier/Function, no dedicated thread pool required by default) — the modern default choice for any new Spring Boot service, with Hystrix knowledge mainly relevant for understanding or maintaining legacy codebases still running it.

Follow-up questions this topic invites — and their answers

Q: Why would thread-pool isolation (Hystrix's approach) ever have been preferable despite its overhead? A: It provided true bulkhead isolation as a side effect — a slow call literally couldn't consume threads beyond its dedicated pool, protecting the rest of the application even under pathological blocking. Resilience4j's lighter functional approach doesn't provide this isolation automatically, which is exactly why Bulkhead & Rate Limiting's separate bulkhead pattern exists as its own explicit tool.

Q: Can a circuit breaker and a retry mechanism be combined, and in what order? A: Yes, and the ordering matters — retries should generally happen INSIDE a closed breaker (retrying while the breaker still considers the dependency healthy), and retrying should stop the moment the breaker opens, exactly the combination covered in Retry & Backoff Strategies — retrying against an already-open breaker would defeat the breaker's whole purpose of stopping load to a struggling dependency.

Q: How would you choose sliding-window-size and failure-rate-threshold for a new integration? A: There's no universal correct value — a smaller window reacts faster to a real outage but is more sensitive to brief blips; start with a reasonable default (the 20-calls/50% shown above is a common starting point) and tune based on the dependency's actual observed failure patterns and how costly a false-positive trip is for that specific integration.

Q: What happens if the fallback method itself depends on something that's also failing? A: This is why fallback design explicitly favors the simplest, most reliable options (a static default, a value already in local memory) — a fallback with its OWN external dependency reintroduces the exact fragility the circuit breaker exists to protect against, defeating the pattern's purpose.

Previous

Configuration Management

Next

Retry & Backoff Strategies

AI Tutor

Lesson: Circuit Breaker Pattern

Quick actions

AI responses can be inaccurate. Verify critical information.