Microservices vs Monolith: Choosing the Right Architecture
The real costs and benefits of microservices vs monoliths, the strangler fig migration pattern, service boundaries, and how to make the architectural decision for your team size and stage.
Microservices vs Monolith: Choosing the Right Architecture
The real costs and benefits of microservices vs monoliths, the strangler fig migration pattern, service boundaries, and how to make the architectural decision for your team size and stage.
What you'll learn
- Start with a monolith — microservices are an organizational solution to an organizational problem
- Split by bounded context (business domain), not by technical layer
- The hidden costs: distributed transactions, operational overhead, network latency, developer experience complexity
- Strangler fig: migrate from monolith incrementally — never big-bang rewrite
- Modular monolith gives 80% of the benefits with 20% of the operational cost
- Adopt microservices only when you have concrete reasons: team size, differential scaling, reliability requirements
Lesson outline
The microservices hype cycle
In 2015-2020, "microservices" became synonymous with "modern engineering." Companies decomposed their monoliths into dozens of small services, hired DevOps teams to manage them, and then wondered why they were slower than before. Netflix, Amazon, and Google run microservices — but they have thousands of engineers to manage them.
The truth: microservices are an organizational solution to an organizational problem. They make sense when multiple teams need to deploy independently, when parts of the system have wildly different scaling requirements, or when you need technology diversity. For most startups and small teams, they are premature.
Start with a monolith — Martin Fowler agrees
"Don't start a new project with microservices, even if you're sure your application will be big enough to make it worthwhile." — Martin Fowler. Build a well-structured monolith with clear module boundaries. Decompose only when you have a specific, concrete reason.
Honest comparison: what you gain and what you pay
| Concern | Monolith | Microservices |
|---|---|---|
| Development speed (early) | ⚡ Fast — one codebase, one deploy | 🐢 Slow — service boundaries, API contracts, local dev setup |
| Development speed (at scale) | 🐢 Slow — merge conflicts, big teams on one repo | ⚡ Fast — teams deploy independently |
| Operational complexity | ✅ Simple — one process to monitor | ❌ Complex — service mesh, distributed tracing, many failure modes |
| Scaling flexibility | ❌ Scale the whole app even if one part is hot | ✅ Scale each service independently |
| Technology diversity | ❌ One language/framework | ✅ Right tool per service |
| Distributed system problems | ✅ No network calls, no partial failures | ❌ Must solve: distributed transactions, circuit breakers, service discovery |
| Developer experience | ✅ Run locally with one command | ❌ Requires Docker Compose with 10+ services, or remote dev environment |
The hidden cost of microservices: latency (network calls replace in-process), consistency (distributed transactions are hard), operational burden (each service needs its own CI/CD, monitoring, scaling policy, on-call runbook).
Service boundary design: how to split correctly
The most common microservices mistake: splitting by technical layer (user-facing service, business logic service, data access service). This creates chatty, coupled services that deploy together anyway. It is not microservices — it is a distributed monolith.
Split by bounded context (Domain-Driven Design): Each service owns one business domain — Users, Orders, Inventory, Payments, Notifications. The domain owns its data (no cross-service joins). Cross-domain operations use APIs or events.
Signs you have the boundary wrong: Services must be deployed together to function, or services frequently call each other synchronously in a chain (A → B → C → D — this is a monolith over the network).
Team ownership: "You build it, you run it" — each service is owned by one team end-to-end. If two teams own the same service, it is not really microservices. Conway's Law: your architecture reflects your team structure.
Two-pizza team rule for service sizing
A service should be manageable by a two-pizza team (6-8 engineers). If it requires more, split it further. If one engineer can manage 5 services, consider merging some. Service granularity should match team granularity.
The strangler fig pattern: migrating from monolith
The strangler fig plant grows around a host tree, eventually replacing it. The Strangler Fig Pattern applies the same idea to software migration: gradually replace monolith functionality with new services, one piece at a time, until the monolith is gone (or just a thin shell).
Steps: (1) Add a routing layer (API gateway or reverse proxy) in front of the monolith. (2) Choose one module to extract — pick one that is clearly bounded and not deeply coupled. (3) Build the new service. (4) Route traffic for that domain to the new service via the routing layer. (5) Delete the old code from the monolith. (6) Repeat.
Anti-pattern: big-bang rewrite. Rewriting the entire monolith from scratch (Duke Nukem Forever antipattern). The new system is never feature-complete before the old one rots. The strangler fig is safer: always have a working system, migrate incrementally.
The routing layer (API gateway) is the key. It is the seam between old and new. Keep it simple — just proxy routing, no business logic.
1# Strangler Fig routing layer2# Gradually route domains from monolith to new microservices34server {5listen 443 ssl;6server_name api.example.com;78# ✅ Migrated: route to new Users microserviceMigrated routes go to new services; unmigrated fall through to monolith9location /api/users/ {10proxy_pass http://users-service.internal:4001;11}1213# ✅ Migrated: route to new Payments microservice14location /api/payments/ {15proxy_pass http://payments-service.internal:4002;16}1718# 🔄 In progress: Orders being migrated19# location /api/orders/ {20# proxy_pass http://orders-service.internal:4003;21# }22The monolith is still the default — no traffic disruption during migration23# ⬛ Not yet migrated: everything else still goes to monolith24location / {25proxy_pass http://monolith.internal:3000;26proxy_set_header X-Forwarded-Host $host;27}28}29# Migration progress: Users ✅, Payments ✅, Orders 🔄, Inventory ⬛, Notifications ⬛
When to choose microservices: the honest checklist
Consider microservices when:
- ✅You have multiple independent teams (>50 engineers) — Each team can own and deploy their service without coordinating with others.
- ✅Parts of the system have wildly different scale requirements — Your image processing needs 100x the resources of your user auth service.
- ✅You have different reliability requirements per domain — Payments needs 99.99% uptime; analytics can tolerate 99.9%.
- ✅You need technology diversity — ML model serving in Python, real-time processing in Go, web API in Node.js.
- ❌You are a startup with < 20 engineers — Operational overhead will slow you down more than it helps.
- ❌Your monolith is well-structured with clear modules — A modular monolith often gives 80% of the benefit with 20% of the cost.
How this might come up in interviews
Architecture questions test judgment and the ability to reason about trade-offs, not knowledge of patterns.
Common questions:
- When would you choose microservices over a monolith?
- How would you migrate a monolith to microservices?
- What are the hidden costs of microservices that are not obvious upfront?
- Explain Domain-Driven Design and bounded contexts.
Strong answers include:
- Starts with "it depends" and asks about team size and scaling requirements
- Knows the strangler fig pattern for migration
- Mentions distributed transaction complexity as a real cost
- Has a nuanced view of when NOT to use microservices
Red flags:
- Always recommends microservices as the "modern" choice
- Cannot explain bounded contexts or DDD
- Does not know what a modular monolith is
- Cannot explain the operational overhead of microservices
Quick check · Microservices vs Monolith: Choosing the Right Architecture
1 / 1
Your 10-engineer startup is deciding between a monolith and microservices. Which factors most strongly favor a monolith?
Key takeaways
- Start with a monolith — microservices are an organizational solution to an organizational problem
- Split by bounded context (business domain), not by technical layer
- The hidden costs: distributed transactions, operational overhead, network latency, developer experience complexity
- Strangler fig: migrate from monolith incrementally — never big-bang rewrite
- Modular monolith gives 80% of the benefits with 20% of the operational cost
- Adopt microservices only when you have concrete reasons: team size, differential scaling, reliability requirements
From the books
Building Microservices — Sam Newman (2021)
Chapter 1: What Are Microservices?
The author of the definitive microservices book now cautions against them for most organizations: "I would be cautious about adopting microservices unless you have a specific need that they address."
Ready to see how this works in the cloud?
Switch to Career Paths for structured paths (e.g. Developer, DevOps) and provider-specific lessons.
View role-based pathsSign in to track your progress and mark lessons complete.
Discussion
Questions? Discuss in the community or start a thread below.
Join DiscordIn-app Q&A
Sign in to start or join a thread.