Monolith vs Microservices
A monolith ships the whole application as one unit; microservices split it into small services that deploy on their own. Learn what each costs, when splitting pays off, and how to split along business boundaries.
In a nutshell
- A monolith is one deployable application. Simple to build, test and run, and the right start for most teams.
- Microservices split the system into services that each own their data and deploy independently.
- The gain is team independence and per-service scaling; the price is network calls, partial failures and operational work.
- Split along business capabilities (orders, payments, catalog), never along technical layers.
Two ways to ship the same product
Imagine a shop with a catalog, a cart, orders and payments. You can build all of it as one application: one codebase, one build, one process (copied onto several servers behind a load balancer), one database. That is a monolith.
A monolith
Diagram as text
- Users → Shop app: HTTP
- Shop app → Database: SQL
Or you can build each capability as its own service, with its own codebase, its own deploy pipeline and its own database. Services talk over the network (HTTP, gRPC or messages), and a gateway gives clients one entry point. Those are microservices.
Microservices
All steps Each service owns its data. Nobody else reads the Payments database; they ask the Payments service.
- The user checks out. The gateway is the single front door.
- The gateway routes the call to the Orders service.
- Orders saves the order in its own database.
- Orders asks Payments to charge the card: a network call that can be slow or fail.
- Payments records the charge in its own database.
- Catalog is untouched; it can deploy, scale or even be down for a moment without blocking checkout.
Diagram as text
- The user checks out. The gateway is the single front door.
- The gateway routes the call to the Orders service.
- Orders saves the order in its own database.
- Orders asks Payments to charge the card: a network call that can be slow or fail.
- Payments records the charge in its own database.
- Catalog is untouched; it can deploy, scale or even be down for a moment without blocking checkout.
What each one costs
| Monolith | Microservices | |
|---|---|---|
| Deploys | All or nothing; one pipeline | Each service on its own schedule |
| Calls between features | Function calls: fast, never lost | Network calls: slower, can time out or fail |
| Data | One database; joins and transactions are easy | One database per service; no cross-service joins or transactions |
| Scaling | Scale the whole app together | Scale only the busy service |
| Teams | Everyone works in one codebase | Each team owns services end to end |
| Debugging | One log, one stack trace | Needs request IDs, tracing and central logs |
| Operations | One thing to run | Many deploys, versions and dashboards |
| Failure | A bug can take everything down | Failures can be contained, or can cascade |
When to split
Microservices solve an organisational problem first: many teams stepping on each other in one codebase and one release train. If you do not have that problem, you mostly get the costs.
- Start with a modular monolith: one deployable, but with clear modules (orders, payments, catalog) that only talk through defined interfaces and do not reach into each other's tables.
- Split a module out when there is a concrete reason: a team needs to ship independently, one part needs very different scaling (video encoding vs the admin panel), or a part needs isolation (payments, for security and compliance).
- Split along business capabilities: a service owns a whole capability and its data. Splitting by technical layer (a "database service", a "validation service") just creates chatty calls.
- Peel off one piece at a time, routing traffic for that feature to the new service while the rest stays in the monolith. This is often called the strangler fig approach.
Living with microservices
If you do run many services, a few patterns stop the network from hurting you:
- Timeouts and retries with backoff on every call, and idempotent operations so retries are safe.
- Circuit breakers: stop calling a service that keeps failing, so threads do not pile up waiting.
- Asynchronous messages instead of synchronous chains where the caller does not need an immediate answer (send the confirmation email later).
- Service discovery, so services find each other as instances come and go.
- Observability: a request ID passed through every call, distributed tracing, and central logs.
- Versioned APIs, so one service can change without breaking its callers.
Common mistakes
- Starting a new product with microservices before the domain and its boundaries are understood.
- Sharing one database between services, so a schema change still needs a coordinated release.
- Long chains of synchronous calls: latency adds up and one slow service stalls all the rest.
- Splitting by technical layer instead of by business capability.
Interview questions
Try answering out loud before you open each one.
Would you build this with microservices?
Say it depends on team size and requirements. For a new product or a small team, start with a modular monolith: faster to build and easier to run. Split out a service when a part needs independent deploys, very different scaling, or isolation (payments). Name the costs: network failures, no cross-service transactions, more operations.
How do you keep data consistent across services without a shared database?
Each service owns its data. For a business process spanning services (order, payment, stock), use a saga: a sequence of local transactions with compensating actions when a step fails, usually driven by events. Accept eventual consistency where the business allows it, and make every step idempotent so retries are safe.
Check yourself
Related topics
Further reading
- Microservices James Lewis and Martin Fowler
- MonolithFirst Martin Fowler
- Goodbye Microservices: From 100s of problem children to 1 superstar Segment engineering blog
Your notes
Saved in this browser as you type.
Finished this topic?
Mark it read to track your progress, then carry on with the next one.