Microservices are simultaneously the most powerful and most misused architectural pattern in modern software engineering. After architecting and deploying microservices across 50+ enterprise engagements, I have opinions.
The Real Case For and Against Microservices
When Microservices Make Sense
- Organizational scale — Multiple teams deploying independently to different services
- Truly different scaling requirements — Payment service needs to scale differently than notification service
- Technology heterogeneity — Different services legitimately benefit from different tech stacks
- Domain boundaries are clear — Well-defined bounded contexts with minimal cross-service transactions
When Microservices Are a Trap
- Small teams (< 10 engineers) — The operational overhead overwhelms the team
- Early-stage products — Requirements are changing too fast for stable service contracts
- Tightly coupled domains — Services that constantly call each other create a distributed monolith
- Performance-critical paths — Network hops add latency that single-process doesn’t
The Patterns That Actually Work
1. API Gateway Pattern
Every external request flows through an API gateway that handles authentication, rate limiting, routing, and observability. Tools: Kong, AWS API Gateway, Traefik.
2. Event-Driven Communication
For asynchronous workflows, services publish events to a message bus (Kafka, SQS, RabbitMQ). This decouples producers from consumers and dramatically improves resilience.
3. Saga Pattern for Distributed Transactions
The hardest problem in microservices: transactions that span multiple services. Sagas — either choreography-based or orchestration-based — handle this without distributed transactions.
4. Circuit Breaker Pattern
Using Resilience4j or Hystrix, circuit breakers prevent cascading failures when downstream services are degraded.
5. Service Mesh for Observability
Istio or Linkerd provides automatic mTLS, service-to-service observability, and traffic management without code changes.
The Kubernetes Reality
Most microservices end up on Kubernetes. Here’s what I’ve learned:
Helm Charts — Use them. Manage configuration complexity across environments.
Resource Limits — Always set CPU and memory limits. Unconstrained pods will cause node pressure and evictions.
Readiness vs Liveness Probes — Both matter. Readiness gates traffic; liveness restarts unhealthy pods.
Horizontal Pod Autoscaler — Configure with appropriate metrics. CPU utilization is a proxy; request count or custom metrics are better signals.
The Observability Imperative
Without observability, microservices are a debugging nightmare. The three pillars:
- Metrics — Prometheus + Grafana for real-time dashboards, SLO tracking
- Logs — Structured JSON logs → Elasticsearch/OpenSearch → Kibana
- Traces — OpenTelemetry + Jaeger/Tempo for distributed request tracing
Rule: Deploy observability before deploying the first service, not after.
Common Mistakes to Avoid
Mistake 1: Services Too Fine-Grained
Nano-services with 200 lines of code and their own database are an antipattern. Start with larger services and split only when a clear boundary emerges.
Mistake 2: Synchronous Request Chains
When Service A calls B, which calls C, which calls D — you’ve created distributed synchronous coupling. Latency adds up, and failures cascade. Use events for non-critical paths.
Mistake 3: Shared Databases
Each service should own its data. Shared databases create tight coupling between services and undermine independent deployability.
Mistake 4: No Contract Testing
Pact or OpenAPI contract tests catch breaking changes before they reach production. Essential for any team operating multiple services.
Migration Strategy: From Monolith to Microservices
The strangler fig pattern works consistently:
- Identify the first service to extract (usually the highest-scaling or most independent domain)
- Build the new service alongside the monolith
- Gradually redirect traffic to the new service
- Remove the extracted code from the monolith
- Repeat
Never try a “big bang” rewrite. It almost always fails.
Building a microservices architecture? Our engineering team has done this dozens of times. Let’s talk about your specific situation.