System Design Series — Part 32
Imagine you're using Amazon during a big sale.
You click "Buy Now."
Behind the scenes, your request travels through multiple services:
-
Order Service
-
Payment Service
-
Inventory Service
-
Notification Service
-
Shipping Service
Everything works perfectly.
But suddenly...
The Payment Service goes down.
Now every incoming request keeps trying to contact the failed service.
Thousands of requests pile up.
Response times increase.
Threads become blocked.
CPU usage spikes.
Soon, even healthy services start slowing down.
This is known as a Cascading Failure.
How do companies like Netflix, Amazon, Uber, and Microsoft prevent one failing service from bringing down the entire system?
The answer is the Circuit Breaker Pattern.
Let's understand it in the simplest way possible.
The Real Problem
Imagine your Order Service depends on the Payment Service.
Normally, the flow looks like this:
Customer
↓
Order Service
↓
Payment Service
↓
Success
Now imagine the Payment Service crashes.
Should the Order Service continue sending requests?
No.
Every failed request wastes:
-
CPU
-
Memory
-
Network bandwidth
-
Database connections
Eventually,
your entire application may become unavailable.
A Simple Real-World Analogy
Imagine electricity in your home.
If there's a short circuit,
the circuit breaker automatically cuts the power.
Why?
To protect the entire electrical system.
It doesn't keep sending electricity into a faulty circuit.
Once the issue is fixed,
the circuit breaker reconnects the power.
Software systems work the same way.
The Circuit Breaker stops sending requests to unhealthy services until they recover.
What is the Circuit Breaker Pattern?
The Circuit Breaker Pattern is a resilience pattern that prevents repeated requests to a failing service.
Instead of continuously retrying failed requests,
it temporarily blocks them.
This gives the failing service time to recover.
It also protects the rest of the system from cascading failures.
How It Works
Step 1
Client sends a request.
↓
Step 2
Application calls another service.
↓
Step 3
Circuit Breaker monitors responses.
↓
Step 4
If failures exceed a threshold,
the circuit opens.
↓
Step 5
Further requests fail immediately.
↓
Step 6
After a timeout,
the breaker tests the service.
↓
If successful,
normal traffic resumes.
The Three States of a Circuit Breaker
1. Closed State
Everything is healthy.
Requests flow normally.
Example:
Client
↓
Order Service
↓
Payment Service
↓
Response
This is the default state.
2. Open State
Too many failures have occurred.
The Circuit Breaker blocks new requests immediately.
Instead of waiting for long timeouts,
the application returns a fallback response.
This protects the system.
3. Half-Open State
After a waiting period,
the Circuit Breaker allows a small number of test requests.
If they succeed,
the breaker closes again.
If they fail,
it returns to the Open state.
This allows services to recover safely.
Real-World Example
Imagine you're booking a ride on Uber.
Ride Service
↓
Payment Service
↓
Receipt Service
If the Payment Service is unavailable,
Uber shouldn't freeze the entire application.
Instead,
the Circuit Breaker detects repeated failures.
It immediately stops calling the Payment Service.
Users receive a friendly message such as:
"Payment service is temporarily unavailable. Please try again in a few minutes."
The rest of the application continues working.
Another Example
Imagine Netflix.
While watching a movie,
the Recommendation Service becomes unavailable.
Should movie playback stop?
Of course not.
Netflix simply skips recommendations temporarily.
The movie keeps playing.
This is graceful degradation.
Why Do We Need Circuit Breakers?
Without Circuit Breakers:
❌ Cascading failures
❌ Thread exhaustion
❌ Long response times
❌ Service overload
❌ Complete outages
With Circuit Breakers:
✔ Faster failure detection
✔ Better system stability
✔ Higher availability
✔ Faster recovery
✔ Better user experience
Production Architecture
A typical architecture looks like this:
Users
↓
API Gateway
↓
Order Service
↓
Circuit Breaker
↓
Payment Service
↓
Database
The Circuit Breaker sits between services,
protecting the caller from unhealthy downstream systems.
Fallback Responses
When a Circuit Breaker is open,
applications often return fallback responses.
Examples:
-
Cached data
-
Default values
-
Friendly error messages
-
Retry suggestions
Users receive a controlled experience instead of a server crash.
Circuit Breaker vs Retry
Many developers confuse these patterns.
Retry
Attempts the request again.
Useful for temporary network issues.
Circuit Breaker
Stops sending requests after repeated failures.
Useful when a service is unhealthy.
In production,
both patterns are often used together.
Retry handles temporary failures.
Circuit Breaker prevents overload.
Popular Frameworks
Many frameworks provide Circuit Breaker support.
Examples:
-
Polly (.NET)
-
Resilience4j (Java)
-
Hystrix (legacy Netflix library)
-
Envoy Proxy
-
Istio Service Mesh
These tools make it easier to build resilient distributed systems.
Advantages
✔ Prevents cascading failures
✔ Protects downstream services
✔ Reduces unnecessary traffic
✔ Improves application stability
✔ Enables graceful degradation
✔ Supports faster recovery
Challenges
Choosing Failure Thresholds
If thresholds are too low,
healthy services may be blocked unnecessarily.
If they're too high,
problems are detected too late.
Fallback Design
Fallback responses should still provide value to users.
Returning generic errors isn't always the best experience.
Monitoring
Track:
-
Failure rates
-
Open circuits
-
Recovery times
-
Timeout frequency
These metrics are essential in production.
Common Developer Mistakes
No Timeout Configuration
Requests shouldn't wait forever.
Always configure reasonable timeouts.
Retrying Forever
Unlimited retries can make failures worse.
Ignoring Monitoring
Without monitoring,
you won't know when circuits are opening frequently.
No Fallback Strategy
A Circuit Breaker without a fallback still creates a poor user experience.
Production-Level Insight
A common misconception is:
"Circuit Breakers prevent failures."
They don't.
Failures are inevitable in distributed systems.
Circuit Breakers simply contain failures before they spread to other services.
That's why they're considered one of the most important resilience patterns in modern microservices.
Interview Tip
A common System Design interview question is:
"How would you prevent cascading failures in a microservices architecture?"
A strong answer should include:
-
Circuit Breaker Pattern
-
Retry Strategy
-
Timeouts
-
Fallback Responses
-
Monitoring
-
Health Checks
-
Bulkheads
Interviewers want to know how you'd keep a production system available when dependencies fail.
Key Takeaways
✔ Circuit Breakers protect applications from repeated failures
✔ They prevent cascading failures across services
✔ A Circuit Breaker has three states: Closed, Open, and Half-Open
✔ Fallback responses improve user experience during outages
✔ Circuit Breakers work well with retries and timeouts
✔ Monitoring is essential for tuning failure thresholds
✔ Modern microservices rely heavily on Circuit Breakers for resilience
One of the biggest lessons in System Design is this:
Failures are unavoidable.
Resilient systems aren't the ones that never fail—they're the ones that fail gracefully.
That's exactly what the Circuit Breaker Pattern helps you achieve.
This is Part 32 of the System Design Simplified series.
Next Article: Part 33 — Retry Pattern Explained Simply
If this article helped you understand the Circuit Breaker Pattern better, consider sharing it with fellow developers.
#SystemDesign #CircuitBreaker #Microservices #SoftwareArchitecture #DistributedSystems #BackendDevelopment #Resilience #Scalability #CloudComputing #SoftwareEngineering #SystemDesignInterview #BackendEngineer #DesignPatterns #Programming #TechArchitecture