Architecture · Updated 2026-06-05

Monolith vs Micro

Start with a monolith. For almost every team, a well-structured ("modular") monolith ships faster, is far easier to operate, and is simpler to reason about. Move to microservices when specific pressures force it: independent team scaling, components with wildly different scaling profiles, or a codebase too large to deploy as one unit. Microservices trade code complexity for distributed-systems complexity — make that trade deliberately, not by default.

Monolith
One deployable unit; one codebase, one process.
Since
1990
By
The default architecture
License
Architecture pattern
en.wikipedia.org/wiki/Monolithic_application ↗
Microservices
Many small, independently deployable services.
Since
2011
By
Popularised by Lewis & Fowler
License
Architecture pattern
martinfowler.com/articles/microservices.html ↗

This is an organizational decision dressed as a technical one. A monolith optimizes for simplicity: one repo, one deploy, in-process calls, easy transactions. Microservices optimize for autonomy: teams ship independently and scale services separately, at the cost of network calls, partial failure, and a lot of operational machinery. The famous advice — "you must be this tall to ride" — still holds.

Quick takes

If you're…

  • You are a startup or small team finding product-market fit Monolith A monolith lets you change anything quickly without distributed-systems overhead.
  • Many teams need to deploy independently without coordinating releases Micro Independent deployability is the core reason microservices exist.
  • Different components have very different scaling needs Micro You can scale just the hot service instead of the whole app.
  • You need multi-entity transactions to stay simple Monolith In-process ACID beats distributed sagas; crossing service boundaries makes consistency hard.
  • Your build/test/deploy of one app has become painfully slow Micro Splitting the unit can restore fast, independent pipelines — if module boundaries are clean.
  • Your observability and on-call maturity is still early Monolith Distributed tracing, retries, and partial-failure handling are table stakes for microservices.
Decision wizard

A few questions, a verdict.

Q1

How many teams ship into this system?

Q2

Do components have very different scaling profiles?

Q3

How mature is your ops / observability?

At a glance

The scorecard.

Dimension
Monolith
Micro
Edge
One pipeline
Independent pipelines
depends
Code complexity
Distributed complexity
Monolith
Scale as a unit
Scale per service
Micro
In-process ACID
Sagas / eventual
Monolith
Team autonomy ecosystem
Shared codebase
Service ownership
Micro
All-or-nothing
Isolated but networked
depends
Local + full traces
Distributed tracing required
Monolith
In depth

Dimension by dimension.

ops

Deployment

depends
Monolith

One artifact to build, test, and ship. Simple, but every change redeploys the whole thing.

Micro

Each service deploys on its own cadence. Independent, but you now run many pipelines and versions.

core

Where complexity lives

edge: Monolith
Monolith

In the codebase: risk of tangled modules if boundaries are not enforced.

Micro

In the network: service discovery, retries, timeouts, partial failure, eventual consistency.

ops

Scaling

edge: Micro
Monolith

Scale the whole app together, even if only one part is hot.

Micro

Scale each service independently to its own load.

core

Data & transactions

edge: Monolith
Monolith

Shared database, in-process ACID transactions across entities.

Micro

A database per service; cross-service consistency needs sagas or outbox patterns.

ecosystem

Team autonomy

edge: Micro
Monolith

Teams share a codebase and coordinate merges and releases.

Micro

Teams own services end to end and ship without blocking each other.

core

Failure mode

depends
Monolith

A bug can take down the whole process, but there is no partial-failure ambiguity.

Micro

Faults isolate to a service, but the network introduces timeouts, retries, and cascading failures.

ops

Debugging & local dev

edge: Monolith
Monolith

Run and step through the whole app locally; stack traces span the codebase.

Micro

Needs distributed tracing; reproducing a flow locally can mean spinning up many services.

When to pick neither

A different shape of problem.

  • You want monolith simplicity with enforced internal module boundaries — the best default for most teams
  • Service-oriented (coarse services)
    A few large services, not dozens of tiny ones — a middle ground
  • Self-contained systems
    Vertical slices that each own UI + logic + data
Situational picks

For specific cases.

A new product still finding its shape

Monolith

Optimize for speed of change. A modular monolith keeps the door open to extract services later.

A large org with many autonomous teams

Micro

Independent deployability and ownership are worth the distributed-systems tax at this size.

One component needs 50× the resources of the rest

Micro

Extract just that component so you can scale it without scaling everything.

A team feeling slowed by a tangled codebase

A modular monolith first

Fix the module boundaries before paying the network tax; most "we need microservices" problems are really "we need clean modules".

Sources

Primary material.

Found this useful?