🇮🇳
🇮🇳
Limited-Time Offer!Get 20% OFF on all live courses
Enroll Now
PrakalpanaLive online tech training
Architecture⏱️ 14 min read📅 Oct 1

Microservices Design Patterns (2026): Gateway, Circuit Breaker, Saga, CQRS, Outbox & More

VR
Venkat Raghavan•Principal Architect
📑 Contents (16 sections)

📌Why Patterns Matter in Microservices

Splitting a system into services trades one set of problems (a big codebase, coupled deployments) for another: network failures, distributed data, partial outages and observability. Microservices design patterns are the proven answers to those problems — and the vocabulary that senior backend and architect interviews use.

Not sure microservices are right for you yet? Read microservices vs monolith first. To build a working system, follow the Spring Boot microservices tutorial.

📌Patterns at a Glance

PatternProblem it solvesSpring / common tooling

API GatewayOne entry point, cross-cutting concernsSpring Cloud Gateway Service DiscoveryFinding dynamic service instancesEureka, Consul, Kubernetes DNS Circuit BreakerCascading failuresResilience4j Database per ServiceLoose coupling of dataSeparate schemas or databases SagaTransactions across servicesKafka events, orchestrators OutboxReliable event publishingOutbox table, Debezium CDC CQRSDifferent read and write modelsRead replicas, projections Event SourcingFull history and auditEvent store, Kafka Strangler FigMigrating from a monolithGateway routing SidecarShared infrastructure concernsEnvoy, Istio, Linkerd Externalised ConfigConfig per environmentSpring Cloud Config, ConfigMaps Distributed TracingDebugging across servicesMicrometer Tracing, OpenTelemetry

📌1. API Gateway

A single entry point that routes requests to services and handles cross-cutting concerns: authentication, rate limiting, CORS, request logging and response aggregation. Clients no longer need to know about every service.

spring:
cloud:
gateway:
routes:
- id: orders
uri: lb://order-service
predicates:
- Path=/api/orders/**
filters:
- name: CircuitBreaker
args:
name: orders
fallbackUri: forward:/fallback/orders

A variant, Backend for Frontend (BFF), gives each client type (web, mobile) its own gateway tailored to its needs.

📌2. Service Discovery

Service instances come and go with scaling and deployments, so hard-coded addresses break. With client-side discovery, services register with a registry such as Eureka and clients look them up (the lb:// URI above). With server-side discovery, a load balancer or platform does it — on Kubernetes, a Service's DNS name is all you need, so many teams drop Eureka entirely.

📌3. Circuit Breaker

When a downstream service is slow or failing, callers that keep waiting exhaust their own threads and fail too — a cascading failure. A circuit breaker tracks failures and, past a threshold, opens to fail fast (or return a fallback), then half-opens to test recovery.

@Service
public class InventoryClient {
private final RestClient restClient;
public InventoryClient(RestClient.Builder builder) {
this.restClient = builder.baseUrl("http://inventory-service").build();
}
@CircuitBreaker(name = "inventory", fallbackMethod = "unknownStock")
@Retry(name = "inventory")
public StockResponse stock(String sku) {
return restClient.get().uri("/api/stock/{sku}", sku)
.retrieve().body(StockResponse.class);
}
private StockResponse unknownStock(String sku, Throwable ex) {
return new StockResponse(sku, -1, "UNKNOWN");
}
}

resilience4j:
circuitbreaker:
instances:
inventory:
sliding-window-size: 20
failure-rate-threshold: 50
wait-duration-in-open-state: 10s
retry:
instances:
inventory:
max-attempts: 3
wait-duration: 200ms

Pair it with timeouts on every remote call, retries with backoff only for idempotent operations, and bulkheads to isolate thread pools.

📌4. Database per Service

Each service owns its data and no other service touches its tables. This is what makes services independently deployable and scalable. The cost: no cross-service joins and no ACID transactions across services — which is why the next patterns exist.

📌5. Saga

A saga replaces a distributed transaction with a sequence of local transactions, each publishing an event or command. If a step fails, compensating transactions undo the earlier steps.

Example — placing an order: create order (PENDING) → reserve stock → charge payment → confirm order. If payment fails: release stock → cancel order.

  • Choreography: services react to each other's events (OrderCreated → InventoryReserved → PaymentCompleted). Simple and loosely coupled, but the flow is hard to see as it grows.
  • Orchestration: a central orchestrator tells each service what to do and handles failures. Easier to understand and monitor for complex flows; tools include Temporal, Camunda or a custom orchestrator service.
  • Make every step idempotent, because events can be delivered more than once.

    📌6. Transactional Outbox

    A service must update its database and publish an event. Doing both separately risks one succeeding and the other failing. The outbox pattern writes the event to an outbox table in the same local transaction as the business change; a relay then publishes it to Kafka or RabbitMQ.

    @Transactional
    public Order placeOrder(OrderRequest req) {
    Order order = orderRepository.save(Order.pending(req));
    outboxRepository.save(OutboxEvent.of("Order", order.getId(), "OrderCreated", toJson(order)));
    return order;
    }

    The relay can poll the table or use change data capture with Debezium. Consumers must still be idempotent.

    📌7. CQRS

    Command Query Responsibility Segregation separates the write model (commands that change state) from the read model (queries optimised for display). The read side is often a denormalised view, a search index such as Elasticsearch, or a cache — updated from events. Use it when reads and writes have very different shapes or scale; it adds complexity and eventual consistency.

    📌8. Event Sourcing

    Instead of storing current state, store the sequence of events that led to it (OrderPlaced, ItemAdded, OrderShipped) and rebuild state by replaying them. You get a complete audit log, time travel and natural event publishing — at the cost of more complex querying (usually solved with CQRS projections) and event schema evolution. Common in finance, ledgers and order management.

    📌9. Strangler Fig

    The safe way to migrate a monolith. Put a gateway in front, then carve out one capability at a time into a new service and route its traffic there, until the monolith is "strangled". No big-bang rewrite, and every step is reversible.

    📌10. Sidecar and Service Mesh

    A sidecar is a helper container deployed alongside each service instance that handles infrastructure concerns — mTLS, retries, traffic shifting, metrics. A service mesh (Istio, Linkerd) manages a fleet of sidecar proxies such as Envoy, moving networking logic out of application code. Valuable at scale; overkill for a handful of services.

    📌11. Externalised Configuration

    Keep configuration out of the build artifact so the same image runs in every environment: Spring Cloud Config, environment variables, or Kubernetes ConfigMaps and Secrets.

    📌12. Observability: Tracing, Logs and Metrics

    A single request may cross ten services. Propagate a trace ID with Micrometer Tracing and OpenTelemetry, ship structured logs with the trace ID to a central store, and expose metrics through Spring Boot Actuator and Prometheus. Without this, debugging microservices is guesswork.

    📌Choosing the Right Patterns

    Start simple: a gateway, discovery (or Kubernetes DNS), circuit breakers with timeouts, database per service and tracing. Add saga and outbox when you have cross-service workflows, and CQRS or event sourcing only when the domain really needs them. Over-engineering is the most common microservices failure.

    These patterns come up constantly in microservices interview questions and system design rounds.

    📌Learn It Live

    Prakalpana's Microservices Architecture course builds a complete Spring Cloud system with these patterns, then runs it on Docker and Kubernetes — live online with an optional 1-on-1 track. WhatsApp or call +91 9243078181 for a free demo.

    VR

    Written by

    Venkat Raghavan

    Principal Architect

    🚀 Master Architecture

    Live online + 1-on-1 Microservices Architecture training · Join 5000+ developers