Microservices Patterns - Complete Internal Map

// Decomposition · communication · data · reliability · observability · security · deployment · transactions

46 total patterns
Decomposition
Communication
Data
Reliability
Transactions
01Decomposition Patterns- How to split a system into microservices
📋Decompose by Business Capabilitydecompose
Split services around stable business capabilities such as users, orders, billing, and shipping.
Business Capabilities ├─ User Management → UserService ├─ Order Processing → OrderService ├─ Billing → BillingService └─ Shipping → ShippingService Teams own capabilities end-to-end
e.g.: Amazon teams for Cart, Search, Checkout
🏛️Decompose by Subdomain (DDD)DDD
Use Domain-Driven Design bounded contexts to create services with their own language and model.
DDD Subdomains Core Domain → OrderService (competitive edge) Supporting → InventoryService (needed but not core) Generic → AuthService (buy/use off-shelf) Each has its own model & language
e.g.: DDD by Eric Evans, Vaughn Vernon
🔄Strangler Fig Patternmigration
Incrementally extract services from a monolith while routing selected traffic to the new system.
Monolith → Microservices migration Step 1: Monolith handles everything Step 2: Extract UserService, route user traffic Monolith → UserService Step 3: Extract OrderService next Step N: Monolith retires completely
e.g.: Real-world monolith to microservice migrations
📦Self-Contained Servicedesign
Design services to answer requests from local ownership data instead of chaining synchronous calls.
Anti-pattern (chatty): OrderSvc → UserSvc → InventorySvc all in one request = cascading failures Self-Contained (correct): OrderSvc → handles locally syncs data async via events
e.g.: Event-driven microservices with local projections
02Communication Patterns- How services talk to each other
↩️Synchronous REST / gRPCsync
Direct request-response communication where the caller waits for a downstream service.
REST (HTTP/JSON) ServiceA → GET /users/123 → UserService ← { id:123, name:"Alice" } ← waits synchronously gRPC (Protobuf / HTTP2) ServiceA → GetUser(id:123) → UserService ← User{id,name} ← strongly typed, faster than REST
e.g.: Express REST, gRPC with Protobuf, GraphQL
📨Asynchronous Messagingasync
Services communicate through a broker so producers and consumers can scale independently.
Message Broker Pattern OrderSvc → publish(OrderPlaced) → [Broker] ↓ ↓ EmailSvc InventorySvc processes processes async async Broker: Kafka, RabbitMQ, SQS, NATS
e.g.: Kafka, RabbitMQ, SQS, NATS
🔔Event-Driven Communicationevents
Services publish domain events when important business facts happen.
Domain Events OrderService emits: → OrderPlaced { orderId, items, userId } → OrderCancelled { orderId, reason } → OrderShipped { orderId, trackingId } Subscribers react: EmailSvc listens → OrderPlaced AnalyticsSvc listens → all events InventorySvc listens → OrderPlaced, OrderCancelled
e.g.: Kafka events, EventBridge, Node EventEmitter
🌐API Gateway Patterngateway
A single entry point routes, authenticates, rate-limits, and protects backend services.
Request Flow through Gateway Client → [API Gateway] │ 1. Authenticate (JWT/OAuth) │ 2. Rate limit check │ 3. Route to service │ 4. Load balance ↓ GET /users → UserService POST /orders → OrderService GET /products → ProductService
e.g.: Kong, AWS API Gateway, Nginx, Traefik
🔍Service Discoverydiscovery
Services register and discover dynamic endpoints instead of hardcoding hostnames or IPs.
Client-Side Discovery ServiceA → query [Service Registry] ← "UserSvc is at 10.0.1.5:8080" → call 10.0.1.5:8080 directly Server-Side Discovery ServiceA → [Load Balancer] LB queries registry internally → routes to correct instance Registry: Consul, Eureka, K8s DNS
e.g.: Consul, Kubernetes DNS, Eureka
🛰️Microservices Communication Deep Divecommunication
Interactive deep dive on service discovery, load balancing, resilience, and live communication behavior.
Client -> Discovery -> Load Balancer -> Service Instance Failures -> Retry / Circuit Breaker Health checks -> dynamic routing
e.g.: Service discovery + round robin + circuit breaker simulation
03Service Design Patterns- How individual services are structured internally
🛸Sidecar Patterninfra
Run a helper container beside the app to handle cross-cutting infrastructure concerns.
Kubernetes Pod ┌─────────────────────────────────┐ │ Pod │ │ ┌────────────┐ ┌─────────────┐ │ │ │ Main App │ │ Sidecar │ │ │ │ :8080 │ │ Envoy Proxy│ │ │ │ │ │ Log Agent │ │ │ └────────────┘ └─────────────┘ │ │ shared network + storage │ └─────────────────────────────────┘
e.g.: Istio Envoy sidecar, Datadog agent, Fluentd
🏗️Backends for Frontends (BFF)design
Create a tailored backend/API layer per client type such as web, mobile, or TV.
Per-Client Backends 📱 Mobile → [BFF-Mobile] → lean payload 🌐 Web → [BFF-Web] → rich payload 📺 TV → [BFF-TV] → media-optimized ↓ all call same microservices [UserSvc][OrderSvc][ProductSvc]
e.g.: Netflix, SoundCloud BFF architecture
🤝Ambassador Patternproxy
Use a local proxy to handle network concerns for a service.
Ambassador as Proxy YourService → [Ambassador] │ handles: ├─ retry logic ├─ circuit breaking ├─ request logging ├─ rate limiting └─ TLS termination ↓ Remote Service / External API
e.g.: Envoy, Ambassador API Gateway, Linkerd
🕸️Service Meshinfra
A mesh of sidecar proxies manages service-to-service traffic transparently.
Service Mesh Topology ServiceA ServiceB [App] ←→ [Proxy] ←────→ [Proxy] ←→ [App] ↕ ↕ [Control Plane: Istio] configures all proxies handles: mTLS, tracing, retries, load balance
e.g.: Istio, Linkerd, Consul Connect
🔄Anti-Corruption Layer (ACL)DDD
Translate between your clean domain model and an external or legacy model.
ACL protects your domain External Legacy System uses: customer_no, acct_ref ↓ [Anti-Corruption Layer] translates: customer_no → userId acct_ref → accountId ↓ Your Clean Domain uses: userId, accountId
e.g.: Legacy adapters, SDK wrappers, domain mappers
04Data Patterns- How services manage and share data
🗄️Database per Servicedata
Each service owns its database and no other service reads or writes it directly.
Data Ownership Model UserService → [PostgreSQL db_users] OrderService → [MongoDB db_orders] ProductService → [Redis db_products] SearchService → [Elastic db_search] ✗ OrderService cannot query db_users directly ✓ OrderService calls UserService API instead
e.g.: Microservices data ownership best practice
✂️CQRSdata
Separate write models from read models so each can optimize for its own workload.
CQRS inside a service WRITE SIDE (Commands) POST /orders → CommandHandler → validates business rules → updates Write DB (normalized) → emits OrderPlaced event READ SIDE (Queries) GET /orders → QueryHandler → Read DB (denormalized, fast) → populated from events
e.g.: Event-sourced systems, denormalized read stores
📜Event Sourcingevents
Store every state change as an immutable event and rebuild state by replaying events.
Event Store (append-only log) [1] AccountCreated { userId: 1, balance: 0 } [2] MoneyDeposited { userId: 1, amount: 500 } [3] MoneyWithdrawn { userId: 1, amount: 200 } [4] MoneyDeposited { userId: 1, amount: 100 } Replay 1→4: balance = 0+500-200+100 = 400 Time travel: replay 1→2 = balance = 500
e.g.: EventStoreDB, Axon, custom event logs
📤Transactional Outboxreliable events
Write business data and outgoing event records in one local database transaction.
Outbox Pattern Flow Begin Transaction: INSERT INTO orders (order data) INSERT INTO outbox (event data) ← same tx Commit Transaction ✓ [Outbox Poller / CDC] reads outbox table → publishes to Kafka/RabbitMQ → marks outbox record as sent Atomic: either both saved or neither
e.g.: Debezium outbox transform, custom outbox poller
🔀API Compositionquery
Aggregate data from multiple services into one response.
Composition Flow Client: GET /order-summary/456 ↓ [OrderComposer] ↓ parallel calls: → UserService.getUser(orderId.userId) → OrderService.getOrder(456) → ProductService.getProducts(orderItems) ← merge all responses return combined OrderSummary to client
e.g.: GraphQL resolvers, BFF aggregators
👂Change Data Capture (CDC)CDC
Capture database changes and publish them as events.
CDC via DB Transaction Log Application → writes to [PostgreSQL] PostgreSQL → WAL (Write-Ahead Log) [Debezium] → reads WAL changes → publishes to Kafka: orders.created { ... } orders.updated { ... } Consumers → react to DB changes
e.g.: Debezium, Kafka Connect, database logs
05Reliability Patterns- Keep services resilient under failure
Circuit Breakerresilience
Stop calling a failing dependency to prevent cascading failures.
Circuit Breaker State Machine CLOSED (normal) requests flow → 5 failures in 10s ↓ OPEN (tripped) all requests → instant fail + fallback wait 30s timeout ↓ HALF-OPEN (testing) let 1 request through success → back to CLOSED fail → back to OPEN
e.g.: opossum, Resilience4j, Hystrix
🚢Bulkhead Patternisolation
Isolate resources so one failing area does not take down the whole system.
Resource Pools (Bulkheads) Thread Pool A (10 threads) → Payment calls Thread Pool B (10 threads) → Inventory calls Thread Pool C (10 threads) → Email calls Payment service hangs → Pool A exhausted Pool B, C still available Inventory, Email still work ✓
e.g.: Thread pools, connection pools, K8s namespaces
🔁Retry with Exponential Backoffretry
Retry transient failures with progressively longer waits and jitter.
Retry Strategy Attempt 1 → fails (wait 100ms) Attempt 2 → fails (wait 200ms) Attempt 3 → fails (wait 400ms) Attempt 4 → success ✓ With Jitter (avoids thundering herd) Wait = min(cap, base * 2^attempt) + random(0..100ms) Idempotency required for safe retries!
e.g.: axios-retry, got retry, AWS SDK retry
⏱️Timeout Patterntimeout
Never wait forever for an outgoing call.
Timeout Configuration connect_timeout: 2s (TCP handshake) request_timeout: 5s (full response) read_timeout: 3s (each read chunk) ServiceA → calls ServiceB → no response in 5s → TimeoutException thrown → return fallback / 503 Without timeout: thread hangs forever
e.g.: fetch AbortController, axios timeout, gRPC deadline
🏃Health Check / Readiness Probeops
Expose endpoints that tell orchestrators whether the service is alive and ready.
Health Probe Types Liveness: GET /health/live Is the process alive? (not deadlocked?) fail → K8s kills + restarts pod Readiness: GET /health/ready Is service ready to receive traffic? fail → removed from load balancer (e.g. still warming up DB connections) Startup: GET /health/startup Did the app finish starting? (slow start)
e.g.: Kubernetes livenessProbe, readinessProbe, Consul health
06Observability Patterns- See what happens inside distributed services
🔎Distributed Tracingobserve
Follow one request across services using trace IDs and spans.
Trace: traceId = abc-123 [Gateway] span 1: 0ms → 120ms [UserSvc] span 2: 10ms → 40ms [OrderSvc] span 3: 45ms → 110ms [DB call] span 4: 50ms → 105ms ← slow! [EmailSvc] span 5:115ms → 118ms Identify bottleneck: DB call at span 4
e.g.: OpenTelemetry, Jaeger, Zipkin, AWS X-Ray
🪵Centralized Logginglogs
Aggregate structured logs from all services into one searchable place.
Log Aggregation Pipeline ServiceA → { traceId, level, msg, ts } ServiceB → { traceId, level, msg, ts } ServiceC → { traceId, level, msg, ts } ↓ log shipper (Fluentd / Filebeat) [Central Store: Elasticsearch / Loki] ↓ [Dashboard: Kibana / Grafana] search: traceId=abc-123 → all logs
e.g.: ELK, Loki + Grafana, Datadog logs, CloudWatch
📊Metrics & Monitoringmetrics
Emit numeric service and resource measurements for dashboards and alerts.
RED Method (per service) Rate → requests per second Errors → error rate % Duration → p50, p95, p99 latency USE Method (per resource) Utilization → CPU/Memory % Saturation → queue depth Errors → error count
e.g.: Prometheus + Grafana, Datadog, New Relic
🏷️Correlation IDobserve
Thread a unique request ID through headers, logs, and downstream calls.
Correlation ID Flow Client → Gateway generates: X-Request-ID: req-789xyz passes header to all services UserSvc: log { reqId: "req-789xyz", ... } OrderSvc: log { reqId: "req-789xyz", ... } PaymentSvc:log { reqId: "req-789xyz", ... } Search logs: reqId=req-789xyz → full trace
e.g.: X-Request-ID, express-request-id, Morgan logger
🔍Log Aggregation + Alertingalerts
Trigger alerts from logs and metrics before users report problems.
Alert Rules (examples) error_rate > 5% → PagerDuty alert p99_latency > 2000ms → Slack warning pod restarts > 3 → immediate page disk usage > 85% → warning email SLO / Error Budget SLO: 99.9% uptime = 43.8 min/month Budget: consumed 40 min this month → freeze deployments, focus on stability
e.g.: PagerDuty, OpsGenie, Grafana Alerts, CloudWatch Alarms
07Security Patterns- Secure service-to-service and client-to-service communication
🔒Mutual TLS (mTLS)security
Both client and server services verify each other with certificates.
mTLS Handshake ServiceA → presents cert to ServiceB ServiceB → presents cert to ServiceA Both verify against trusted CA Encrypted + mutually authenticated channel Service Mesh handles this automatically
e.g.: Istio mTLS, Linkerd, SPIFFE/SPIRE
🎫Token-Based Auth (JWT)auth
Use signed tokens to propagate identity and authorization claims.
JWT Flow Client → POST /auth/login AuthSvc → signs JWT { userId, roles, exp } Client → sends JWT in Authorization header ServiceA → verify signature locally ✓ ServiceA → extract userId, roles from payload Stateless — no session store needed
e.g.: jsonwebtoken, jose, Auth0, Keycloak, Cognito
🚫Zero Trust Architecturesecurity
Authenticate and authorize every request, even inside the private network.
Zero Trust per request Old model: inside network = trusted ServiceA calls ServiceB → just works Zero Trust model: verify everything ServiceA calls ServiceB → present identity (mTLS cert / JWT) → B verifies identity → B checks authorization policy → B logs the access → allow or deny
e.g.: BeyondCorp, SPIFFE/SPIRE, Istio AuthorizationPolicy
🔑Secrets Managementsecrets
Store and rotate credentials in a vault instead of hardcoding them.
Secrets Vault Pattern ✗ Bad: DB_PASS=secret123 in code / env ✓ Good: HashiCorp Vault Service → authenticate to Vault Vault → return secret (time-limited) Service → use secret, auto-renew Rotation: new secret → services pick up automatically without redeploy
e.g.: HashiCorp Vault, AWS Secrets Manager, encrypted K8s Secrets
08Deployment Patterns- How microservices are deployed and released safely
🔵🟢Blue-Green Deploymentdeploy
Run two identical environments and switch traffic after the new one passes checks.
Blue [v1.0] ← 100% live traffic Green [v2.0] ← deploy + test here Switch: Blue → standby Green → 100% live traffic Rollback: flip switch back instantly
e.g.: AWS CodeDeploy, Kubernetes service switching
🐦Canary Deploymentdeploy
Release to a small percentage of traffic, monitor, then gradually increase.
100 users total: 5% → v2 (canary 🐦) — monitor closely 95% → v1 (stable) metrics OK? → increase to 25% → 50% → 100% metrics bad? → rollback 5% → 0% instantly
e.g.: Argo Rollouts, Flagger, Spinnaker, Istio weights
🔄Rolling Updatedeploy
Replace old instances with new instances gradually.
Rolling Update Progress Start: [v1][v1][v1][v1][v1] Step 1: [v2][v1][v1][v1][v1] Step 2: [v2][v2][v1][v1][v1] Step 3: [v2][v2][v2][v1][v1] Done: [v2][v2][v2][v2][v2] API must be backward-compatible!
e.g.: Kubernetes Deployment default rollout
👻Shadow / Mirror Deploymentdeploy
Mirror production traffic to a new version, but discard shadow responses.
Duplicate live traffic to new version silently Users only receive response from old version Compare latency, errors, and results of both versions Best for: DB migrations, ML models, critical rewrites
e.g.: NGINX mirror module, Envoy traffic shadowing, Istio mirror
💥Recreate Deploymentdeploy
Stop old version first, then start the new version.
Terminate ALL current instances, then deploy new version Guarantees no version mixing - clean state Has intentional downtime window Best for: dev/staging, breaking schema changes
e.g.: Kubernetes strategy: Recreate, controlled maintenance windows
⚖️A/B Testing Rolloutexperiment
Route different user segments to different versions to compare outcomes.
Route users by attributes (region, plan, ID) Measure business outcomes: conversions, engagement, revenue Not only release safety - this is product experimentation Best for: feature flags, pricing tests, UX experiments
e.g.: LaunchDarkly, Statsig, Optimizely, custom feature-flag routers
🏗️Immutable Infrastructuredeploy
Never patch running instances; build a new image and replace them.
Mutable (old way) Server → SSH in → apt update → patch (drift: servers become snowflakes) Immutable (correct) Code change → build new Docker image → push to registry → deploy new pods → terminate old pods Every deployment is predictable
e.g.: Docker, Kubernetes, Packer AMIs, GitOps with ArgoCD
🎯Deployment Interview Cardinterview
Layer-level interview focus across deployment strategies.
Q: Blue-Green vs Canary - when to choose each? A: Blue-Green for instant rollback and strict cutover. A: Canary for gradual risk control with live metrics.
Tip: mention rollback speed, observability, and infra cost tradeoffs.
09Distributed Transaction Patterns- How to maintain data consistency across services
⚗️Saga Pattern - Choreographytransactions
Services publish and react to events without a central coordinator.
Choreography Saga OrderSvc → emit: OrderCreated PaymentSvc → hear: OrderCreated → process payment → emit: PaymentProcessed StockSvc → hear: PaymentProcessed → reserve stock → emit: StockReserved ShipSvc → hear: StockReserved → ship On failure: compensating events PaymentSvc → emit: PaymentFailed OrderSvc → hear: PaymentFailed → cancel order
e.g.: Kafka choreography, EventBridge rules
🎛️Saga Pattern - Orchestrationtransactions
A central orchestrator commands each service step and handles compensation.
Orchestration Saga [Saga Orchestrator] drives the flow: Step 1: call PaymentSvc.charge() → success → go to step 2 → fail → compensate Step 2: call StockSvc.reserve() → success → go to step 3 → fail → call PaymentSvc.refund() Step 3: call ShipSvc.schedule() Full visibility: orchestrator knows state
e.g.: Temporal.io, AWS Step Functions, Conductor, Camunda
📤Outbox + Inbox Patternconsistency
Use outbox records for reliable sends and inbox records for idempotent receives.
Outbox (sender side) BEGIN TX: INSERT orders → order data INSERT outbox → { msgId, event, status:pending } COMMIT Poller: read outbox → publish to Kafka → mark sent Inbox (receiver side) Receive event { msgId: "m-456" } CHECK inbox table: msgId=m-456 exists? → YES: already processed, skip (idempotent) → NO: process + INSERT inbox(m-456)
e.g.: Debezium outbox, custom outbox poller, inbox table
🔒Two-Phase Commit (2PC)consistency
A coordinator asks participants to prepare, then commits or rolls back all participants.
2PC Protocol Phase 1 — PREPARE: Coordinator → "prepare?" → DB-1, DB-2, DB-3 DB-1 → "ready ✓" DB-2 → "ready ✓" DB-3 → "ready ✓" Phase 2 — COMMIT: Coordinator → "commit!" → all DBs all commit atomically ✓ If DB-2 says "not ready": Coordinator → "rollback!" → all DBs
e.g.: XA transactions; rarely preferred in microservices
Production microservices use patterns from many categories together: boundaries, communication, data ownership, failure handling, observability, security, release safety, and consistency all matter.