5 Microservices Patterns That Actually Work in Production
Real-world patterns for building resilient microservices—from circuit breakers to saga orchestration. No theory, just what we use on client projects.
Microservices sound great in theory: independent deployments, polyglot stacks, team autonomy. But production is where most teams hit reality—cascading failures, data consistency nightmares, and debugging distributed traces at 2 AM.
We've deployed microservices for e-commerce platforms, fintech apps, and SaaS products. Here are 5 patterns that consistently work.
1. Circuit Breakers (Fail Fast, Recover Gracefully)
Problem: Service A calls Service B. Service B is down. Service A waits, times out, retries—and brings down the whole system.
Solution: Wrap external calls in a circuit breaker. After N failures, "open" the circuit and fail fast. Periodically retry (half-open state) to detect recovery.
// Using resilience4j or similar library
const breaker = new CircuitBreaker({
failureThreshold: 5,
timeout: 3000,
resetTimeout: 30000,
});
async function callServiceB() {
return breaker.execute(() => fetch('https://service-b/api'));
}
Why it works: Prevents cascading failures. Service A stays responsive even when dependencies fail.
2. Saga Pattern (Distributed Transactions Without Locks)
Problem: You're processing an order across 3 services (Payment, Inventory, Shipping). Payment succeeds, Inventory fails. How do you roll back Payment?
Solution: Use choreography (events) or orchestration (coordinator). Each service emits success/failure events. On failure, compensating transactions reverse prior steps.
Example (Choreography with Kafka):
- Payment emits
PaymentSucceeded
- Inventory consumes it, reserves stock, emits
InventoryReserved
orInventoryFailed
- On
InventoryFailed
, Payment consumes it and refunds viaPaymentRefunded
Why it works: No distributed locks. Each service owns its data and compensates locally.
3. API Gateway (Single Entry Point, Multiple Backends)
Problem: Frontend makes 10 API calls to load a dashboard. High latency, complex authentication.
Solution: Use an API Gateway (Kong, AWS API Gateway, or custom Node.js/Go service). It:
- Routes requests to the right service
- Aggregates responses (Backend-for-Frontend pattern)
- Handles auth, rate limiting, and caching
Why it works: Reduces frontend complexity. Centralizes cross-cutting concerns (auth, logging).
4. Event Sourcing + CQRS (Audit Trail + Read Optimization)
Problem: You need both transactional writes and high-speed reads. SQL queries on normalized tables are slow.
Solution:
- Event Sourcing: Store all state changes as events (e.g.,
OrderCreated
,OrderShipped
). - CQRS: Separate write models (event store) from read models (denormalized views in Postgres, Elasticsearch).
Example:
- Write: Append
OrderShipped
event to Kafka. - Read: Consumer updates a
orders_view
table optimized for queries.
Why it works: Audit trail by default. Read models tailored for performance.
5. Service Mesh (Observability + Traffic Control)
Problem: You have 20 microservices. How do you enforce timeouts, retries, and mTLS without coding it in each service?
Solution: Deploy a service mesh (Istio, Linkerd, Consul). It injects sidecars (proxies) that handle:
- Traffic routing (canary deploys, A/B tests)
- Observability (distributed tracing, metrics)
- Security (mTLS, authorization)
Why it works: Decouples infrastructure concerns from business logic. Works across polyglot services.
Bonus: What We Avoid
- Shared databases: Defeats the purpose of microservices. Each service owns its data.
- Sync calls for everything: Use async messaging (Kafka, RabbitMQ) for non-critical paths.
- Premature decomposition: Start with a well-structured monolith. Split when team or scaling pressures justify it.
Conclusion
Microservices aren't magic. They trade complexity for flexibility. Use these patterns, monitor relentlessly (Prometheus + Grafana + Jaeger), and have runbooks for failure scenarios.
Need help? We've built microservices architectures for platforms handling $50M+ GMV. Book a call to discuss your migration.