Microservices
A microservices architecture splits an application into small services, each responsible for one business capability (orders, payments, inventory) and each deployable on its own. Services own their data and talk to each other over the network through APIs or messages.
The goal is organizational as much as technical: let many teams change and release their part of the system without coordinating with everyone else.
Diagram
Section titled “Diagram”flowchart LR
client[Web and mobile clients] --> gw[API gateway]
gw --> orders[Orders service]
gw --> catalog[Catalog service]
gw --> payments[Payments service]
orders --> odb[(Orders DB)]
catalog --> cdb[(Catalog DB)]
payments --> pdb[(Payments DB)]
orders -- OrderPlaced event --> bus{{Message broker}}
bus --> payments
bus --> notify[Notification service]
How it works
Section titled “How it works”- One capability per service. Boundaries follow business capabilities or domain-driven design bounded contexts, not technical layers.
- Database per service. No other service reads a service’s tables directly. Data is shared only through its API or events.
- Independent deployment. Each service has its own pipeline and can be released without redeploying the others.
- Communication over the network. Synchronous calls (REST, gRPC) for queries that need an immediate answer, and asynchronous events for everything that can wait.
- Edge routing. An API gateway handles routing, authentication and rate limiting for external clients.
- Independent releases: teams ship on their own schedule.
- Targeted scaling: scale only the services under load.
- Fault isolation: with good design, one failing service degrades a feature instead of the whole application.
- Technology freedom: each service can use the language or datastore that suits it.
- Clear ownership: a team owns a service end to end.
- Distributed-systems complexity: network failures, latency, retries and partial outages become everyday concerns.
- Data consistency is harder: transactions across services need sagas or eventual consistency instead of a single database transaction.
- Operational overhead: dozens of pipelines, deployments, dashboards and on-call rotations.
- Harder debugging: a single request may cross many services, so distributed tracing becomes essential.
- Testing across services: contract tests and integration environments are needed to catch breaking changes.
When to use it
Section titled “When to use it”- Several teams work on the same product and block each other’s releases.
- Parts of the system have very different scaling or availability needs.
- The domain is well understood, so service boundaries can be drawn with confidence.
- The organization already has mature CI/CD, observability and platform automation.
When to avoid it
Section titled “When to avoid it”- A small team or an early-stage product whose domain is still changing. Boundaries drawn too early are expensive to move.
- No automated deployment or monitoring in place yet.
- The main motivation is “it’s modern” rather than a specific scaling or team problem.
In these cases, a modular monolith usually delivers most of the benefit at a fraction of the cost.
Common pitfalls
Section titled “Common pitfalls”- The distributed monolith. Services that must be deployed together, or that call each other in long synchronous chains, carry the costs of both styles and the benefits of neither.
- Shared databases. Two services writing to the same tables are coupled, whatever the deployment diagram says.
- Services that are too small. Splitting by entity (“customer-address-service”) instead of capability multiplies network calls for no gain.
- Ignoring idempotency. Retries and redelivered messages will happen; handlers must tolerate duplicates. See idempotency.
- Observability as an afterthought. Without correlation IDs and tracing from day one, production incidents become guesswork.
Related patterns
Section titled “Related patterns”- Event-driven architecture
- API gateway
- Saga
- Strangler fig migration
- Circuit breaker
- Backend for frontend
Glossary: bounded context, eventual consistency, saga, idempotency
Further reading
Section titled “Further reading”- Sam Newman, Building Microservices (2nd edition)
- Chris Richardson, Microservices Patterns
- Martin Fowler and James Lewis, “Microservices” (martinfowler.com)
Written and edited by Abhinav Taduka, enterprise software architect.