Search

Monolith vs Microservices: Why Companies Switch (Both Ways)

The short answer

Quick answer: A monolith is one application, built and deployed as a single unit, usually with one database. Microservices split the system into many small services, each owning its own data, deployed independently and talking over the network. Microservices let large organisations ship and scale parts of a system independently, but they add the full difficulty of distributed systems: network failures, data consistency, and far more operational work. Companies move to microservices when a monolith slows many teams down, and some move back when the overhead outweighs the benefit. For most teams, a well-structured monolith is the right starting point.

What each one is

Monolith

  • One codebase, one build, one deployable.
  • Modules call each other with ordinary function calls.
  • One database, so transactions and joins span the whole system.

Microservices

Martin Fowler and James Lewis's article Microservices gave the style its common definition:

  • Small services organised around business capabilities (orders, payments, search).
  • Each is independently deployable.
  • Each owns its data; no other service touches its database.
  • They communicate through APIs or asynchronous messages.
  • Teams choose their own tools within limits and own their service in production.

Side by side

MonolithMicroservices
DeploymentOne unit; everything ships togetherEach service ships on its own
Calls between partsIn-process, fast, reliableOver the network, slower, can fail
DataOne database, ACID transactionsA database per service, eventual consistency
ScalingScale the whole appScale individual services
TechnologyOne stackMixed, per service
Team fitOne team or a fewMany autonomous teams
Local developmentRun one thingRun or mock many things
DebuggingOne stack traceA trace across many services
Operational overheadLowHigh

Why companies move to microservices

  • Teams block each other. With hundreds of engineers in one codebase, merges conflict, builds take an hour, and a release needs everyone's sign-off. Independent services let teams ship on their own schedule.
  • Different parts need different scaling. If image processing needs fifty machines and the admin panel needs one, scaling them together is wasteful.
  • Fault isolation. A memory leak in recommendations should not take down checkout.
  • Different technical needs. One part suits Python and machine learning libraries; another needs low-latency Go.
  • Clear ownership. A team owns a service end to end, including being on call for it.

The underlying force is organisational. Conway's law observes that systems tend to mirror the communication structure of the organisations that build them. Microservices are as much a way to structure teams as to structure software.

What it costs

Every function call that becomes a network call inherits the problems described in why distributed systems are hard:

  • Calls fail and slow down. You need timeouts, retries, circuit breakers and idempotency.
  • No shared transactions. An order that touches inventory, payments and shipping can no longer be one database transaction. You need patterns such as sagas (a sequence of local transactions with compensating actions) and must accept eventual consistency.
  • No joins across services. Data must be fetched through APIs or duplicated.
  • Operational load. Dozens of pipelines, dashboards and on-call rotations. You need container orchestration (see what Kubernetes does), service discovery, and centralised logs, metrics and tracing.
  • Harder testing. A realistic test needs many services running, or careful contract tests.
  • Versioning. Services deploy independently, so every API change must stay compatible with older callers.
  • Performance. Chains of network calls add latency.

Small teams often find they have traded a code organisation problem for an infrastructure problem.

The distributed monolith

The worst outcome is splitting the code into services without achieving independence:

  • Services share a database.
  • A feature needs changes to five services, deployed in a fixed order.
  • One service failing breaks most of the others.

This has all the costs of microservices and none of the benefits. It usually comes from splitting by technical layer, or drawing boundaries before the domain was understood.

Why some companies move back

Several well-known engineering teams have publicly described consolidating services back into fewer, larger ones. The common reasons:

  • Cost. Passing data between many small components can be far more expensive than doing the work in one process.
  • Overhead out of proportion to team size. A team of ten running forty services spends its time on plumbing.
  • Boundaries were wrong. Features kept crossing service lines.
  • Performance. In-process calls are faster than network calls.

Moving back is not failure. It reflects that the right architecture depends on the organisation's size and the problem's shape, and both change.

The middle path: a modular monolith

You can get much of the benefit of clear boundaries without the network:

  • One deployable, but strictly separated modules.
  • Each module has a public interface; others may not reach into its internals.
  • Each module owns its tables, even within one database.
  • Boundaries are enforced by tooling, not just by convention.

A modular monolith is easier to operate and gives you well-defined seams. If one module later needs independent scaling or its own team, it can be extracted into a service with far less risk. Fowler's Monolith First argues exactly this: start with a monolith, and split it only once you understand where the boundaries belong.

How to decide

Stay with (or start with) a monolith if:

  • You have one team, or a few.
  • The product and domain are still changing quickly.
  • You do not have a platform team or mature automation.

Consider microservices if:

  • Many teams are slowed by sharing one codebase and release.
  • Parts of the system have very different scaling or reliability needs.
  • You have solid CI/CD, monitoring and on-call practices already.

If you split, do it gradually:

  1. Modularise inside the monolith first.
  2. Extract one service where the pain is greatest and the boundary is clear.
  3. Route traffic to it bit by bit, leaving the rest in place (the "strangler" approach).
  4. Give the new service its own data.
  5. Prefer asynchronous messaging for communication where you can; see how message queues work. For synchronous APIs, see REST vs GraphQL vs gRPC.

Frequently asked questions

Are microservices better than a monolith?

Not inherently. They solve problems of scale in teams and traffic, and create problems of complexity. Many successful products run on monoliths.

How big should a microservice be?

Big enough to own a complete business capability and be run by one team. Size in lines of code is not the measure.

What is a modular monolith?

A single deployable application with strongly enforced internal module boundaries. It offers clear structure without distributed-system overhead.

Can microservices share a database?

They can, but it couples them tightly: a schema change can break several services. Each service owning its data is a core principle of the style.

Conclusion

Monolith versus microservices is a trade between simplicity and independence. A monolith keeps everything in one place and easy to reason about. Microservices let many teams move separately, at the price of distributed complexity. Start simple, keep modules clean, and split only when a specific, real pain justifies it.

Related articles

Sources and further reading

Usama Muneer

Usama Muneer

Coder, Blogger, Tech Speaker & Web Technologies Enthusiast. Passionate about working on open-source Programming languages & Tools while utilizing my Product Development skills.

Your experience on this site will be improved by allowing cookies Cookie Policy