Use Cases and Real-world Examples
Microservices Patterns: Use Cases and Real-world Examples
Microservices patterns are not abstract dogma — each one exists to solve a specific failure mode that appears when you split a system into independently deployed services. The goal of this lesson is to stop treating patterns as a checklist and start treating them as answers to concrete questions: How do I keep data consistent across services? How do I stop one slow service from taking down the rest? How does a client talk to fifty services without knowing about all of them?
The core problem is this: a monolith gets consistency, a single database transaction, and one deploy for free. The moment you break it into services, you lose all three. Every microservices pattern is a way to buy back one of those lost guarantees at an acceptable price. If you can name the guarantee a pattern restores, you understand the pattern.
How the core patterns work, precisely
Four patterns cover most real interview and production scenarios:
- API Gateway — a single entry point that fronts many services. It handles cross-cutting concerns (TLS termination, authn/authz, rate limiting, request routing, response aggregation) so each service and each client stays simple. The client makes one call; the gateway fans out. Variant: Backend-for-Frontend (BFF), one gateway per client type (mobile, web, partner API).
- Saga — replaces a distributed ACID transaction with a sequence of local transactions, each in one service, linked by events. If step N fails, you run compensating transactions (semantic undos) for steps 1..N-1. Two flavors: choreography (services react to each other's events, no central brain) and orchestration (a coordinator service issues commands and tracks state).
- Circuit Breaker — wraps calls to a dependency in a state machine (
CLOSED→OPEN→HALF_OPEN). After a threshold of failures it tripsOPENand fails fast instead of piling up threads on a dead dependency, then probes recovery inHALF_OPEN. - CQRS + Event Sourcing — separate the write model from read models, and (optionally) persist state as an append-only log of events, projecting read-optimized views asynchronously.
A worked scenario: e-commerce checkout at scale
Consider a checkout flow handling 2,000 orders/sec at peak. Placing an order touches three services: Order, Payment, and Inventory, each owning its own database. There is no shared transaction, so we use an orchestration Saga:
- Order service creates the order in
PENDINGand emits a command to the orchestrator. - Orchestrator calls Payment (charge card). Payment's local commit succeeds → emit
PaymentCaptured. - Orchestrator calls Inventory (reserve stock). If the item is out of stock, Inventory fails. The orchestrator now runs a compensating transaction:
RefundPayment, then moves the order toCANCELLED.
Now the payment gateway is a third party with a p99 latency of ~300ms. During an outage, calls hang for a 5s timeout. At 2,000 QPS, threads pile up: 2000 × 5s = 10,000 in-flight requests within one second — thread pools exhaust and the whole checkout tier stalls (a cascading failure). A circuit breaker set to trip after, say, 50% failures over a 10s rolling window flips to OPEN and fails those calls in under 1ms, returning a "payment temporarily unavailable" response and freeing threads for healthy traffic. The read side (order history) is served by a CQRS read replica projected from events, so browsing stays fast even while writes are degraded.
Trade-offs: when to use, when not — versus alternatives
Saga vs. distributed transaction (2PC): Use a Saga when services span databases and you can tolerate eventual consistency plus writing compensating logic. Its price is that there is no isolation — other transactions can see intermediate states (an order briefly PENDING with money charged but stock unconfirmed). Prefer 2PC only inside a tightly-coupled boundary with a resource manager that supports it; at internet scale 2PC's synchronous locking kills availability, which is why almost no one uses it across microservices.
Orchestration vs. choreography Saga: Choreography (services subscribe to each other's events) is simplest for 2–3 steps and avoids a central component, but with 6+ steps the event web becomes impossible to reason about — no one place tells you "where is order 123 in the flow?" Use orchestration once you need visibility, complex branching, or timeouts; accept that the orchestrator is a new component to build and scale.
Circuit breaker vs. plain retries/timeouts: Timeouts bound a single call; retries help transient blips but amplify load during a real outage. A circuit breaker is the pattern for a sustained dependency failure. Use all three together — timeout + limited retry with backoff + breaker — not one instead of another.
API Gateway vs. direct client-to-service: Use a gateway when you have many clients or many services and need centralized auth, throttling, and aggregation. Skip it (or keep it thin) for a single internal client or a tiny system — a heavy gateway becomes a bottleneck and a single point of failure, and stuffing business logic into it recreates the monolith.
CQRS/Event Sourcing: Use when read and write loads differ wildly or you need an audit log / temporal queries. Do not reach for it by default — it adds eventual consistency between write and read models plus event-versioning pain. For simple CRUD it is pure overhead.
Pitfalls an interviewer probes
- Non-idempotent compensations and retries. Sagas retry steps after crashes, so every step and every compensation must be idempotent (keyed by an idempotency token) or you double-charge a card. Interviewers love asking "what if the orchestrator crashes right after Payment succeeds but before recording it?"
- Compensations that cannot truly undo. You can refund money, but you cannot un-send a shipping email. Real designs need semantic compensation (issue a credit) or a pivot transaction after which the saga can only go forward.
- Circuit breaker tuning. Thresholds too tight cause false trips; too loose and it never protects you. A breaker with no
HALF_OPENprobe stays open forever; a shared breaker across all endpoints trips on one bad route. Also: what does the caller show the user when OPEN? — the fallback matters. - Dual-write / outbox. Writing to a DB and publishing an event are two operations; a crash between them loses the event. The expected answer is the transactional outbox pattern (write event to an outbox table in the same local transaction, relay it via CDC).
- Gateway as a hidden monolith. Piling routing plus business logic plus aggregation into the gateway couples all teams to one deploy — the exact coupling microservices were meant to remove.
Key takeaways
- Every microservices pattern buys back a guarantee the monolith gave for free — name the guarantee (consistency, isolation, availability, simplicity of client contract) and the pattern's purpose is clear.
- Sagas trade ACID isolation for cross-service consistency; the hard parts are idempotency, compensating transactions, and reliable event publishing via the outbox pattern.
- Circuit breakers protect against sustained dependency failure by failing fast; combine them with timeouts and bounded retries rather than choosing one.
- Match the pattern to scale: gateways, CQRS, and orchestration earn their complexity only under many clients, skewed read/write loads, or long multi-step flows — for small systems they are net cost.
🤖 Don't fully get this? Learn it with Claude
Stuck on Use Cases and Real-world Examples? Open Claude, copy a block below, and it'll teach you this exact concept — visually and interactively.
Build the mental picture, not memorization.
I just read a lesson on **Use Cases and Real-world Examples** (System Design) and want to truly understand it. Explain Use Cases and Real-world 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.
Socratic — adapts to where you're stuck.
Teach me **Use Cases and Real-world 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.
Active recall exposes what you missed.
Quiz me on **Use Cases and Real-world 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.
Intuition + hook + flashcards for long-term memory.
Help me remember **Use Cases and Real-world 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.