Microservices patterns describe common ways to design, connect, protect, and monitor independently deployable services. This cheat sheet helps students recognize when each pattern is useful and what tradeoffs it introduces. It is especially helpful when comparing distributed system designs, cloud architectures, and enterprise application patterns.
The focus is on practical reference rules rather than implementation details for a single programming language.
The core ideas include splitting systems around business capabilities, routing requests through gateways, and keeping services discoverable as instances change. Reliability patterns such as circuit breakers, retries, bulkheads, and timeouts help prevent cascading failures. Data patterns such as sagas, CQRS, and event sourcing handle consistency when no single database owns every transaction.
Observability patterns use logs, metrics, traces, and correlation IDs to make distributed behavior understandable.
Key Facts
- Decompose by business capability: each service should own one cohesive business function and its data.
- API Gateway rule: client request -> gateway -> one or more backend services, with routing, authentication, and aggregation handled at the edge.
- Service discovery rule: service instance registers location -> registry stores it -> client or gateway resolves a healthy instance before calling.
- Circuit breaker states are closed, open, and half-open, and calls are blocked when repeated failures move the breaker to open.
- Retry rule: retry only transient failures, use exponential backoff such as delay = baseDelay * 2^attempt, and avoid retrying non-idempotent operations without safeguards.
- Saga pattern rule: long business transaction = sequence of local transactions plus compensating actions for rollback-like behavior.
- CQRS separates command models that change state from query models that read state, often using different schemas or stores.
- Observability rule: every request should carry a correlation ID so logs, metrics, and traces can be connected across services.
Vocabulary
- Microservice
- A small, independently deployable service that owns a specific business capability and usually manages its own data.
- API Gateway
- A service entry point that routes client requests, applies cross-cutting policies, and may combine responses from multiple services.
- Circuit Breaker
- A reliability pattern that stops calls to a failing dependency after a threshold is reached so the system can recover.
- Saga
- A distributed transaction pattern that coordinates multiple local transactions using events or commands and compensating actions.
- CQRS
- Command Query Responsibility Segregation is a pattern that separates write operations from read operations.
- Event Sourcing
- A persistence pattern where state is stored as a sequence of events rather than only as the latest current value.
Common Mistakes to Avoid
- Splitting services by technical layer, such as controller, service, and database, is wrong because it creates distributed versions of a monolith instead of business-aligned services.
- Sharing one database across many microservices is wrong because it couples deployments, hides ownership, and makes schema changes risky.
- Retrying every failed request immediately is wrong because it can amplify outages and overload a dependency that is already unhealthy.
- Using sagas as if they provide traditional ACID rollback is wrong because sagas rely on local transactions and compensating actions, so intermediate states may be visible.
- Skipping observability until production is wrong because distributed failures are hard to diagnose without structured logs, metrics, traces, and correlation IDs.
Practice Questions
- 1 A payment service fails 5 times in a row, and the circuit breaker threshold is 3 failures. What state should the circuit breaker enter after the third failure?
- 2 A retry policy uses delay = 100 ms * 2^attempt, starting with attempt = 0. What delays are used for attempts 0, 1, 2, and 3?
- 3 An order workflow reserves inventory, charges a card, and schedules shipping across three services. Which pattern is best for coordinating this workflow without a single distributed database transaction?
- 4 Explain why a team might choose CQRS for a high-traffic product catalog, and describe one tradeoff that comes with that choice.
Understanding Microservices Patterns Reference
A microservice is not simply a small program. It is a program with its own deployment, network boundary, failure modes, and usually data ownership. A call across that boundary is far slower and less certain than a function call inside one program.
Networks can delay messages, duplicate them, or lose a response after the receiving service has already completed the work. This is why a design needs clear contracts.
Teams should define request formats, error responses, versioning rules, and ownership before writing many services. Splitting too early can create a distributed monolith, where every small change still requires several teams and services to coordinate.
Service boundaries affect both technical work and human work. A useful boundary matches a business area that can change at its own pace, such as ordering, billing, or shipping. If two services must be changed together every week, their boundary may be wrong.
Each service should avoid reading another service's database directly. Direct database access makes internal details into shared dependencies. Instead, services exchange information through APIs or events.
Events are records that something happened, such as an order being placed. They support loose coupling, but receivers must handle duplicate and out of order delivery.
Idempotent processing matters here. An idempotent operation gives the same final result even if the same message arrives more than once.
Consistency becomes more complicated when one user action affects several services. Consider an online store. Reserving stock, taking payment, and creating delivery each happen in separate places.
A saga coordinates these steps without pretending that one database transaction controls everything. If delivery creation fails after payment succeeds, the system may need a refund or a pending order state. Compensation is not always a perfect undo.
A shipped item cannot be unshipped in the same simple way that a database row can be deleted. Students should notice the business rules behind each compensation. Event sourcing keeps a history of state changes, which can help with auditing and rebuilding views.
CQRS can make reads fast and focused, but read data may briefly lag behind recent commands. Users may need clear status messages while the system catches up.
Reliability patterns work best as a group, not as isolated switches. A timeout stops a service from waiting forever. A retry may recover from a short network problem, but many retries can overload an already failing dependency.
Backoff and random delay spread repeated attempts over time. Bulkheads reserve resources so a slow feature cannot consume every connection or worker. Circuit breakers reduce pressure on a dependency that is failing repeatedly.
These controls need measured limits based on real traffic. Observability provides that evidence. Trace records show the path of one request, metrics reveal rates and delays, and structured logs explain specific events.
Correlation IDs must travel through every service and asynchronous message. In real projects, students should practice following one order or login across logs, then test failures such as a delayed database, a duplicate event, or an unavailable payment service. Those tests reveal whether the architecture fails safely.