Skip to content

Module 05 // Async and communicationLesson 19 / 3418 min read

Microservices vs monolith

A monolith is one app deployed as a unit; microservices split the app into small services that each own one business area and deploy independently. Microservices help large teams move fast, but add a lot of distributed complexity.

Think of it like this

Analogy

A monolith is a single big restaurant kitchen. Everyone works in one room with one set of recipes. Communication is easy (you just shout), but when there are 200 cooks it gets crowded, and changing one station's layout disturbs everybody.

Microservices are a food hall: separate stalls for pizza, sushi and dessert, each with its own staff, kitchen and menu. Each stall can change its recipes on its own schedule. But now you need signs to find stalls, a shared payment system, and someone to coordinate when an order needs food from three of them.

The problem it solves

As a product and its team grow, a single codebase can become a bottleneck. Every deploy ships everything, so one team's bug blocks another team's release. Test suites take an hour. Everyone needs to understand everything. One memory leak in a rarely used feature takes down the whole app. And you can't scale the busy part (search) without scaling the rest.

But splitting too early creates a different set of problems, often worse ones.

A real example

Example

A marketplace outgrows its monolith

An online marketplace started as one app with one database, and for three years that was the right call. Now 60 engineers work in the same codebase. A deploy needs sign-off from five teams, and a bug in the reviews page once took down checkout.

They split out two services first. Payments has strict security rules and its own team. Search needs very different hardware. Each gets its own database and talks to the rest through APIs, with an API gateway in front.

Deploys get faster for those teams. They also gain new problems: network calls that time out, data spread over several databases, and the need for tracing to see why a request was slow.

How it works

Monolith

A monolith is one deployable application with one database. A modular monolith organizes the code into well-separated modules (orders, users, payments) that talk through clear internal interfaces. It keeps most of the benefits of separation with none of the network problems, and it's the recommended starting point for most teams.

Microservices

Microservices split the system along business areas. Each service:

  • owns one area (orders, payments, catalog) and its own data;
  • deploys independently, on its own schedule;
  • talks to others over APIs (REST, gRPC) or events (lessons 17–18).
Architecture
Loading diagram…
Clients reach services through an API gateway. Each service owns its data; services also talk through events.
  • Clients to API gateway
  • API gateway to Users service
  • API gateway to Orders service
  • API gateway to Payments service
  • Users service to Users DB
  • Orders service to Orders DB
  • Orders service to Event bus: OrderPlaced
  • Payments service to Event bus

The supporting pieces

  • API gateway: one entry point for clients. It routes /orders/* to the orders service, checks auth tokens, applies rate limits and logs requests.
  • Service discovery: services come and go as they scale, so callers look them up by name in a registry, or use the platform's DNS (as in Kubernetes).
  • Service mesh (optional): a proxy next to each service that handles retries, timeouts, encryption between services and metrics, without changing app code.
  • Observability: with requests crossing many services, distributed tracing (lesson 24) becomes essential.

What gets harder

ConcernMonolithMicroservices
A call between featuresIn-memory function callNetwork call that can fail or be slow
Transactions across areasOne database transactionSagas and eventual consistency
Debugging a requestOne log fileTraces across many services
Local developmentRun one appRun or mock many services
DeployOne pipelineMany pipelines; version compatibility

Splitting well

  • Split along business capabilities, not technical layers (not a “database service”).
  • Each service should be deployable alone. If two services must always deploy together, they're really one.
  • Avoid chatty chains: if one page needs ten synchronous calls in a row, latency and failure risk add up.
  • Use the strangler fig pattern to migrate: route one feature at a time from the monolith to a new service until the monolith is gone.

Trade-offs

What you gain

  • Teams own, deploy and scale their services independently.
  • A failure in one service can be contained.
  • Each service can use the best tools for its job, and the hot parts scale on their own.

What it costs you

  • Network calls add latency and new failure modes.
  • Data is spread out: cross-service queries and transactions are hard.
  • Much more infrastructure: gateways, discovery, tracing, many pipelines.
  • Easy to end up with a “distributed monolith”: tightly coupled services that are worse than one app.

When not to use it

  • Small teams and young products, where the domain boundaries aren't clear yet. Start with a modular monolith.
  • When the main problem is performance; splitting rarely makes things faster by itself.

In the cloud

Containers and KubernetesEvery major cloud sells this as a managed service, so you configure it rather than build it.

AWS2

Azure2

Google Cloud2

How you’d set it up

An API gateway routes each path to its own service; services find each other by name.

  1. Amazon API Gateway
  2. Application Load Balancer
  3. ECS services on Fargate
  4. Per-service databases

Service discoveryEvery major cloud sells this as a managed service, so you configure it rather than build it.

AWS2

Azure2

Google Cloud2

Interview questions

Try answering out loud first, then open the model answer.

Monolith or microservices for a new startup? Why?

Model answer

A modular monolith. With a small team the biggest risks are speed and figuring out the product, and microservices add operational overhead, network failures and data consistency problems that slow you down. I'd keep strong module boundaries, with separate packages, no reaching into other modules' tables, and clear interfaces, so that if a part later needs to scale or be owned by a separate team, it can be extracted.

How do you handle a business transaction that spans several services, like placing an order?

Model answer

With a saga instead of a distributed transaction. For example: Orders creates the order as “pending” and emits OrderCreated; Inventory reserves stock and emits StockReserved (or StockFailed); Payments charges and emits PaymentCaptured (or PaymentFailed); Orders then marks the order confirmed, or triggers compensating steps such as releasing stock or refunding. Each step is idempotent and its event is published reliably with the outbox pattern. The user sees “processing” until the saga finishes.

What's a distributed monolith and how do you avoid it?

Model answer

It's a system split into services that still have to change, deploy and stay up together, through shared databases, synchronous call chains or shared libraries with business logic. You get the costs of microservices without the independence. Avoid it by drawing boundaries around business capabilities, giving each service its own data, preferring events over long synchronous chains, versioning APIs to stay backward compatible, and checking that each service can be deployed on its own.

Quiz

Pick an answer to see whether it’s right and why.

  1. 01A team of 5 engineers is building a new product. What's usually the best starting point?
  2. 02In microservices, why should each service own its own database?
  3. 03What does an API gateway do?
  4. 04Which is a good first service to split out of a monolith?
  5. 05Service A calls B, which calls C, which calls D. Each is 99.9% available, and all must succeed. What happens to availability?
  6. 06What's a “distributed monolith”?

0 of 6 answered

Key terms

Monolith
One application that contains all features, deployed as a single unit.
Microservices
An app split into small services, each owning one business area and its own data, deployed independently.
API gateway
The single front door for clients that routes requests to services and handles auth, limits and logging.
Service discovery
How services find the current network addresses of other services by name.
Service mesh
A layer of proxies beside each service that handles retries, encryption and metrics for service-to-service traffic.

Progress is saved in this browser only.