system-design · intermediate
Microservices Architecture — Independently Deployable Pieces
Start here
Microservices architecture structures a product as many small(ish) services that:
- Are independently deployable
- Own their data (ideally)
- Communicate over the network (HTTP, gRPC, events)
- Align with team boundaries (Conway’s law awareness)
What you will learn
- Define microservices vs modular monolith.
- See benefits: autonomy, selective scale, isolation.
- See costs: latency, consistency, ops, debugging.
- Work a complete commerce split example.
- Apply rules of thumb for service boundaries.
- Avoid distributed monolith anti-patterns.
What you should know first
| Topic | Why |
|---|---|
| Client–server | Services are servers to each other |
| API gateway | Edge entry |
| Sync vs async | Interaction styles |
Words you need before we begin
| Term | Plain English |
|---|---|
| Service | Independently deployable process with a clear API. |
| Bounded context | Domain modeling boundary for ownership. |
| Distributed monolith | Many services that must deploy together and share databases. |
| Saga | Cross-service workflow with compensations. |
| Contract | API/event agreement between services. |
| Fan-out | One request triggers many downstream calls. |
Simple story: food court vs one mega-kitchen
A food court (microservices) has specialized stalls with their own inventory. A single mega-kitchen (monolith) shares one freezer and schedule. Stalls scale sushi independently, but getting a full meal may mean multiple queues and more walking (network hops).
The problem microservices try to solve
- Large teams blocking on one release train
- Scaling the whole monolith for one hot endpoint
- Fault isolation (one module’s memory leak killing everything)
- Polyglot needs (rare but real)
Step-by-step: adopting thoughtfully
Step 1 — Start with modular monolith boundaries
Packages/modules with clear APIs even inside one deployable.
Step 2 — Identify split candidates
Different scale, different compliance, different team ownership, frequent independent change.
Step 3 — Define contracts first
Versioned APIs/events; consumer-driven tests.
Step 4 — Separate data
No shared write DB across services. Integrate via APIs/events.
Step 5 — Provide platform basics
Discovery, gateway, observability, CI/CD, on-call.
Step 6 — Choose sync vs async per use case
User-facing authorize vs async email.
Step 7 — Measure the tax
Track deploy frequency gains vs incident complexity.
Visual mental model
flowchart LR
GW[API gateway] --> Cat[Catalog service]
GW --> Cart[Cart service]
GW --> Ord[Order service]
Ord --> Pay[Payment service]
Ord -->|events| Mail[Email service]
Cat --> CatDB[(Cat DB)]
Ord --> OrdDB[(Ord DB)]
Learning question: Why is a shared company_db for all services a red flag?
Caption: It couples deploys and schemas—distributed monolith territory.
Complete worked example: commerce split
Starting situation
Monolith slows releases; catalog team blocked by checkout freezes.
Decisions
| Service | Owns | Talks via |
|---|---|---|
| Catalog | Products | Sync read APIs |
| Cart | Cart contents | Sync |
| Orders | Order lifecycle | Sync create; events after |
| Payments | Charges | Sync with idempotency |
| Notify | Email/SMS | Events |
Failure design
Payments timeout → fail order create carefully; never double charge (idempotency keys). Email down → order still succeeds.
Outcome
Catalog deploys thrice daily. Cost: need gateway, tracing, contract tests, more dashboards.
How it works in production
- Containers + orchestrators
- Central logging/metrics/tracing
- SLOs per service
- Platform teams enable product teams
Failure modes
| Mode | Impact | Mitigation |
|---|---|---|
| Chatty sync meshes | Latency & cascades | Design coarser APIs; async |
| Shared DB | Coupling | Split data ownership |
| No distributed tracing | Un-debuggable | Trace every hop |
| Too many services too soon | Ops collapse | Fewer, larger services |
| Distributed monolith deploys | Lockstep releases | True independence tests |
| Unowned services | Pager voids | Clear ownership |
Trade-offs
| Benefit | Cost |
|---|---|
| Team autonomy | Coordination overhead |
| Selective scaling | Duplicated cross-cutting concerns |
| Tech flexibility | Fragmentation risk |
| Fault isolation potential | Partial failure complexity |
Compare with related concepts
| Concept | Difference |
|---|---|
| Modular monolith | One deployable, strong modules |
| SOA (historic) | Related ideas; often heavier ESBs |
| Functions/serverless | Fine-grained deploy; different ops |
| EDA | Communication style often used with microservices |
Common misunderstandings
- “Microservice = small file count.” Size is about independence, not LOC pride.
- “Network is reliable.” Design for partial failure.
- “One DB is fine if schemas differ.” Still coupling.
- “We will find boundaries later.” Wrong splits are expensive—iterate carefully.
- “Kubernetes means we have microservices.” Platform ≠ architecture.
Check your understanding
- Name three benefits and three costs.
- What is a distributed monolith?
- Why own data per service?
- When keep a monolith?
- How do events help side effects?
Practice
- Propose three services for a ride-sharing app and their data.
- Identify a bad split (e.g., splitting by technical layer only).
- Design failure behavior when payments is down.
- List minimum platform capabilities before splitting.
- Critique a diagram with 40 services for a 6-person team.
Deeper production notes
Team topology
If you cannot staff on-call for a service, do not create it. Ownership is the scarce resource.
Contract testing
Without consumer-driven tests, independent deploys become production roulette.
Strangler pattern
Extract gradually from a monolith rather than big-bang rewrites.
Additional teaching scenarios
Scenario A — peak load day
Traffic multiplies by ten. Mark which failure modes appear first and the first mitigation for each.Scenario B — mixed versions
Half the fleet runs an old build. Which assumptions break? Prefer one deploy window of compatibility.Scenario C — five-sentence teach-back
Explain the core idea without acronyms.Scenario D — metrics and alerts
List three metrics and one alert tied to user impact or scarce resources.Scenario E — non-goals
Name two problems this technique should not solve.Scenario F — ownership
Who owns dashboards, code, and pages?Revision summary
- Microservices = independent deploy + ownership + network.
- Benefits trade against distributed complexity.
- Prefer modular monolith until pain is real.
- Split data and invest in platform & contracts.
Glossary
| Term | Definition |
|---|---|
| Microservice | Independently deployable service with clear ownership. |
| Distributed monolith | Services coupled in practice. |
| Bounded context | Domain boundary guiding splits. |
Abbreviations and terminology
- LOC — Lines of code
- ESB — Enterprise service bus
- SLO — Service level objective
- CI/CD — Continuous integration / delivery
What to learn next
Extra teaching notes for first-time builders
Write the single bottleneck you are protecting before picking tools. Name the signal that tells you the design is working for users, not only that internal counters move. When reviewing a change related to this lesson, ask what happens when the component is slow for ten minutes, down entirely, or running twice. Prefer small explicit failure modes that operators can understand at 3 a.m.
Document ownership for dashboards, code, and pages. Undocumented mechanisms become folklore and then outages. Prefer designs that tolerate mixed versions for at least one deploy window so rollouts do not require perfect global simultaneity.
Napkin math helps: estimate peak rate, multiply by payload size, and ask whether the design still holds when a dependency is at half capacity. If the answer depends on luck, add bounds, backpressure, or shedding before production traffic arrives.
Extra teaching notes for first-time builders
Write the single bottleneck you are protecting before picking tools. Name the signal that tells you the design is working for users, not only that internal counters move. When reviewing a change related to this lesson, ask what happens when the component is slow for ten minutes, down entirely, or running twice. Prefer small explicit failure modes that operators can understand at 3 a.m.
Document ownership for dashboards, code, and pages. Undocumented mechanisms become folklore and then outages. Prefer designs that tolerate mixed versions for at least one deploy window so rollouts do not require perfect global simultaneity.
Napkin math helps: estimate peak rate, multiply by payload size, and ask whether the design still holds when a dependency is at half capacity. If the answer depends on luck, add bounds, backpressure, or shedding before production traffic arrives.
Extra teaching notes for first-time builders
Write the single bottleneck you are protecting before picking tools. Name the signal that tells you the design is working for users, not only that internal counters move. When reviewing a change related to this lesson, ask what happens when the component is slow for ten minutes, down entirely, or running twice. Prefer small explicit failure modes that operators can understand at 3 a.m.
Document ownership for dashboards, code, and pages. Undocumented mechanisms become folklore and then outages. Prefer designs that tolerate mixed versions for at least one deploy window so rollouts do not require perfect global simultaneity.
Napkin math helps: estimate peak rate, multiply by payload size, and ask whether the design still holds when a dependency is at half capacity. If the answer depends on luck, add bounds, backpressure, or shedding before production traffic arrives.
Extra teaching notes for first-time builders
Write the single bottleneck you are protecting before picking tools. Name the signal that tells you the design is working for users, not only that internal counters move. When reviewing a change related to this lesson, ask what happens when the component is slow for ten minutes, down entirely, or running twice. Prefer small explicit failure modes that operators can understand at 3 a.m.
Document ownership for dashboards, code, and pages. Undocumented mechanisms become folklore and then outages. Prefer designs that tolerate mixed versions for at least one deploy window so rollouts do not require perfect global simultaneity.
Napkin math helps: estimate peak rate, multiply by payload size, and ask whether the design still holds when a dependency is at half capacity. If the answer depends on luck, add bounds, backpressure, or shedding before production traffic arrives.
FAQ from first-time learners
Q: How small should a service be?
A: Small enough for one team to own fully; large enough to avoid chatty networks.
Q: Is a modular monolith “legacy”?
A: No—it is often the correct default.
Q: Do microservices require Kubernetes?
A: No, but you need some mature deploy and discovery story.
Track: Software Design and Architecture
Previous: Fan-out on Write vs Fan-out on Read
Next: Notification System Design — Reference Architecture
By Shubham Jain