CMD Guide
HomeSystem DesignMicroservices Patterns

System Design Examples

Use Cases and System Design Examples

As we've seen so far, the Circuit Breaker pattern can be a powerful strategy for building resilient systems. But where and how can it be used effectively? In this section, we'll explore some common use cases for the Circuit Breaker pattern and provide some system design examples that illustrate the pattern in action.

Use Case 1: Microservices Architecture

Microservices architectures have gained popularity due to their ability to create loosely coupled, independently deployable components. But they also introduce more points of communication, and consequently, more points of failure.

Consider a typical e-commerce application split into microservices such as user management, product catalog, shopping cart, and order processing. Each service might depend on others to fulfill requests. For example, the order processing service might rely on the product catalog to validate product availability and the user management service to validate user credentials.

Now, what happens if the product catalog service starts failing? Without any safeguards in place, the failures would start impacting the order processing service, leading to a degraded user experience or even a total outage.

Here, the Circuit Breaker pattern can be invaluable. By placing a Circuit Breaker in front of the product catalog service, the order processing service can detect failures quickly and stop sending requests to the failing service. It can instead fall back to a cached product list or even fail gracefully by providing a relevant error message to the user.

This is just one instance of how the Circuit Breaker pattern can be used effectively in a microservices architecture. By isolating faults and preventing them from cascading, it can significantly enhance the system's resilience and ensure high availability.

Use Case 2: External API Integration

Integrating external APIs into your system is another scenario where the Circuit Breaker pattern can shine. External APIs are outside of your control and can be unpredictable. They can have downtime, latency spikes, or rate limiting policies that can impact your system.

Imagine a weather forecasting application that pulls data from several external weather APIs. If one of these APIs starts to fail or becomes slow, it could degrade the overall performance of the application or even cause it to fail.

By implementing a Circuit Breaker for each external API, the application can detect and isolate the problematic API, ensuring that its issues do not affect the overall system. The application could then either switch to another API or provide a degraded service until the faulty API recovers.

Use Case 3: Database Access

Database access is a crucial part of most applications, and database issues can quickly lead to severe system problems. Whether it's due to network issues, resource contention, or database server failures, these problems can cause slow responses or errors in your application.

A Circuit Breaker can help here too. For instance, in a system with a read-heavy database load, a Circuit Breaker can monitor the database's health. If it detects an increasing error rate or latency, it can trip and redirect read operations to a read replica or a cache, ensuring continuous service availability.

The same can be applied for write operations, albeit with more caution. In the case of increased errors or latency, a Circuit Breaker could trip and temporarily buffer write operations. However, it's crucial to handle this carefully, as data consistency can be at risk, and the buffer could become a bottleneck.

Real-world Use Cases

The Circuit Breaker pattern is commonly used in large-scale systems and has been proven in real-world scenarios:

These examples highlight a common theme: using circuit breakers to isolate and contain failures in one part of a system so that the whole system doesn’t collapse. In practice, many libraries and frameworks provide ready-made circuit breaker implementations. For Java, aside from Netflix Hystrix (now in maintenance mode), there’s Resilience4j, and for .NET there’s Polly, among others. Cloud platforms and service meshes have them built-in. But regardless of the implementation, the concept remains the same. Engineers designing large-scale systems routinely include circuit breakers in their toolkit for resilience.

System Design Example: Distributed Social Media Platform

Now let's imagine a distributed social media platform. The platform comprises several services: User Management, Post Management, Feed Generation, and more. Each of these services might be running on multiple nodes for high availability and load balancing.

In this scenario, the Circuit Breaker pattern can be applied in several places. For instance, Circuit Breakers could be placed in front of the User Management service. This would allow services relying on it, such as the Post Management and Feed Generation, to quickly detect when the User Management service is struggling. They could then reduce the load on the User Management service by providing a degraded service, such as displaying cached user information or providing simplified post feeds.

Similarly, a Circuit Breaker could be applied to the interaction between the Post Management service and the database storing the posts. If the database starts experiencing problems, the Circuit Breaker could trip and the Post Management service could start serving cached posts or stop accepting new posts temporarily.

Even external services, like an email service used for notifications, could have a Circuit Breaker. If the email service starts failing, the Circuit Breaker would prevent the notification feature from impacting the rest of the system.

In a distributed setting like this, we could also consider using a shared Circuit Breaker for each service, stored in a distributed cache. This would help maintain consistency across all nodes, ensuring that if a Circuit Breaker trips on one node, it trips on all nodes. However, this would need to be balanced against the additional complexity and potential performance impact.

To complement the Circuit Breakers, the system should also have a comprehensive monitoring and alerting setup. It should monitor the state of all Circuit Breakers and alert developers or system administrators when a Circuit Breaker trips. This would ensure quick detection and remediation of issues.

Remember, the goal is not to eliminate failures - they are inevitable in any system. Instead, the objective is to manage failures effectively, preventing them from cascading and causing system-wide outages. The Circuit Breaker pattern, when used judiciously and in conjunction with other resiliency patterns, can play a key role in achieving this goal.

The circuit-breaker state machine

A circuit breaker is not just a "try again later" wrapper; it is a state machine with three states and two knobs. The two knobs are the failure threshold (how many failures trip it) and the open timeout (how long it stays open before allowing a trial call). The three states are:

Worked example: payment-gateway breaker

Imagine an order service calling a payment gateway. We configure the breaker with failureThreshold = 5 failures within a rolling 10-second window and an openTimeout = 30 seconds. The gateway starts timing out:

  1. Calls 1–5 time out. On the fifth timeout the breaker trips to OPEN.
  2. Call 6, 50 ms later, fails fast with a fallback to "pay later / retry checkout."
  3. 30 seconds later the breaker moves to HALF_OPEN and call 7 is allowed through as a probe.
  4. If call 7 succeeds, the breaker closes and normal traffic resumes. If it fails, the breaker opens for another 30 seconds.

This example makes the operational point concrete: the breaker is not a retry policy; it is a load-shedding policy that protects both caller and callee.

When NOT to use a circuit breaker

Breakers are not free and not universal:

Operational knobs and monitoring

In production you monitor:

Tune the threshold against the baseline error rate, not against zero. If the downstream normally returns 0.5% errors, a threshold of 3 failures in 10 seconds will trip constantly; a threshold of 20 in 60 seconds is closer to "real outage."

Takeaways

End-to-end: which tool for the brownout — breaker, retry-budget, or load-shed?

The examples above show where to place a breaker. The harder, more interview-relevant question is which resilience tool is the right primary defense for a given failure — because a breaker, a retry-budget, and load-shedding all "handle" a struggling dependency, but they fix different problems and the wrong pick makes the outage worse. Work one concrete system end-to-end.

The system. A product-search API at the edge serves 1,000 req/s. To render each result page it calls a pricing service (a fleet of nodes behind discovery) for live prices. Normal pricing latency is 15 ms; the search API runs a bounded worker pool. Now pricing starts erroring. Let f = the fraction of pricing calls that fail.

The crossover, derived. Retry and breaker are the same-direction tools (protect caller from callee); the switch between them is a number. A retry-once policy adds roughly f extra calls (one retry per failed call), which must stay within the retry budget b. So retry-first is safe only while

f ≤ b   →   with b = 10%,   f* = 0.10

Below f* = 10% failure rate, a bounded retry-budget delivers higher availability at trivial added load and the breaker should stay closed. Above f* = 10%, the budget is exhausted, retries become pure amplification, and the breaker must take over and shed the dependency. That is exactly why the two compose in production — retry inside, breaker outside: the retry-budget handles the small-f regime, the breaker catches the large-f regime the budget can no longer absorb, and load-shedding sits orthogonally at admission for the self-overload case. A senior answer names all three and the ~10% crossover; a junior answer reaches for whichever one they learned first.

🤖 Don't fully get this? Learn it with Claude

Stuck on System Design Examples? Open Claude, copy a block below, and it'll teach you this exact concept — visually and interactively.

🎨 Explain it visually

Build the mental picture, not memorization.

I just read a lesson on **System Design Examples** (System Design) and want to truly understand it. Explain System Design Examples from first principles using ONE vivid real-world analogy and a visual mental model — draw it as ASCII art or a clear step-by-step diagram — with a concrete example using real numbers. Then ask me one question to check I got the mental picture, and wait for my reply. If you're unsure or a claim isn't standard, say so and reason from first principles instead of guessing.
🤔 Walk me through it (interactive)

Socratic — adapts to where you're stuck.

Teach me **System Design Examples** interactively. Ask me ONE guiding question at a time, wait for my answer, and adapt to my confusion — build the idea with me step by step instead of explaining it all at once. If you're unsure or a claim isn't standard, say so and reason from first principles instead of guessing.
🧪 Quiz me & fix my gaps

Active recall exposes what you missed.

Quiz me on **System Design Examples** with 5 questions, easy to tricky, ONE at a time. Tell me if each answer is right; at the end, explain clearly what I got wrong and why. If you're unsure or a claim isn't standard, say so and reason from first principles instead of guessing.
🧠 Make it stick

Intuition + hook + flashcards for long-term memory.

Help me remember **System Design Examples** for the long term: give the one-sentence intuition, a memorable hook/mnemonic, a tiny worked example, and 3 active-recall flashcards (Q -> A). If you're unsure or a claim isn't standard, say so and reason from first principles instead of guessing.

📝 My notes