Start with a monolith. Extract microservices later when you have a specific reason to. This is the advice from the people who built microservices at Netflix, Amazon, and Google.
What they are
Monolith — one application, one codebase, one deployment. Everything runs together.
Microservices — many small, independent services. Each handles one thing (users, payments, notifications) and communicates over HTTP/gRPC/message queues.
Side-by-side
| Monolith | Microservices | |
|---|---|---|
| Complexity | Low | High |
| Deployment | One thing to deploy | Many things to deploy |
| Debugging | Easy (one process, one log) | Hard (distributed tracing) |
| Team size | 1-20 developers | 20+ developers |
| Scaling | Scale everything together | Scale individual services |
| Data consistency | Easy (one database) | Hard (distributed transactions) |
| Latency | Low (in-process calls) | Higher (network calls) |
| Infrastructure | Simple | Complex (K8s, service mesh, etc.) |
| Time to market | Fast | Slow (initial setup) |
Why monoliths are underrated
A well-structured monolith can handle millions of users. Shopify, Stack Overflow, and Basecamp all run monoliths. GitHub ran as a monolith for years.
The monolith advantages:
- Simple — one repo, one deploy, one database, one log file
- Fast development — no network calls between services, no API contracts to maintain
- Easy debugging — set a breakpoint, step through the code
- Refactoring — rename a function and your IDE updates everything
- Transactions — database transactions just work
When microservices make sense
- Large teams (50+ developers) — teams can own and deploy services independently
- Different scaling needs — your image processing needs 10x the compute of your user API
- Different tech stacks — one team uses Python for ML, another uses Go for the API
- Fault isolation — a bug in notifications shouldn’t crash payments
- Independent deployment — ship the payment service without redeploying everything
The progression
- Start with a monolith — get to market fast, validate the idea
- Structure it well — separate concerns with modules/packages (not services)
- Extract services when needed — when a specific part needs independent scaling or a different team owns it
- Don’t extract everything — most of your app can stay as a monolith
The microservices tax
Before choosing microservices, you need:
- Container orchestration (Kubernetes)
- Service discovery
- Distributed tracing (Jaeger, Datadog)
- API gateway
- Message queues (RabbitMQ, Kafka)
- CI/CD per service
- Monitoring per service
That’s months of infrastructure work before you write a single feature.
See also: What is Docker? | What is Kubernetes? | Docker vs. Kubernetes