Microservices vs Monolith
Architecture choice. Default to monolith unless specific pain points demand splitting.
1 credit
Monolith — the right default
- One codebase, one deploy, one DB. Simple to reason about.
- Refactoring across features = single PR. No API coordination.
- Local dev = one process. No docker-compose with 12 services.
- DB transactions work. No distributed consistency problems.
- At <50 engineers and <10M req/day, monolith almost always wins.
When to split
- Team size: one codebase becomes a merge-conflict zoo (~30+ active engineers).
- Different tech stacks — ML (Python), API (Go), website (TypeScript) legitimately different.
- Different scale/cost profiles — image processing needs GPU; auth API needs lots of small instances.
- Different release cadences — billing team ships monthly; product team ships hourly.
- Regulatory isolation — PII subsystem needs VPC + separate audit.
Hidden microservices costs
5 itemsNetwork calls are slow + unreliable
In-process call: 1µs. HTTP call: 1-10ms + failure modesDistributed transactions
You can't. Use sagas, outbox pattern, or eventual consistencyDebugging across services
Need traces (OpenTelemetry), correlation IDs, log aggregationOps complexity
N services × deploy + monitor + secrets + alerts + on-callData ownership
Shared DB schemas leak across services. Each service needs its own tablesModular monolith (the middle path)
- Keep one deploy, but enforce internal module boundaries — `billing/` can't import from `feed/` directly.
- Each module owns its DB tables; cross-module reads go through a service interface.
- If a module needs to split out later, the boundary is already drawn. Cheap migration.
- Shopify, GitHub, Basecamp all run this pattern at huge scale.