skip to content

What is the 'monolith-first' heuristic often attributed to Martin Fowler, and what's the reasoning for starting a new system as a monolith even when the team expects it will eventually need to scale like microservices?

level: middleimportance: must knowfreq 70%

answer

  1. Fowler & Lewis heuristic
  2. boundaries unknown early on
  3. wrong boundary cheap in monolith, expensive in services
  4. extraction via strangler fig later
  5. Segment's consolidation story

basics

~20 s

Start new projects as one simple app (a monolith) instead of many small services, because early on you don't yet know where the real boundaries between parts of your system should be — splitting too soon locks in guesses that are often wrong.

solid answer

~50 s

The monolith-first heuristic says that for a new system whose domain boundaries aren't yet well understood, you should build it as a single deployable application first, and only split pieces out into separate services once real usage has revealed which boundaries are stable and which parts genuinely need independent scaling or deployment. The reasoning is that getting service boundaries wrong is expensive in microservices — merging two over-split services means renegotiating APIs and migrating data across a network boundary — while getting module boundaries wrong in a monolith is cheap, since it's just refactoring code in one codebase and one transaction. Microservices also carry fixed operational overhead (service discovery, monitoring, per-service pipelines) that a small team or unproven product often can't afford yet. The counter-case: if the organization already knows its domain boundaries well, or already has the operational maturity, starting with several services can be reasonable.

go deeper

for a junior

Should be able to state the basic heuristic — build one app first, split later — and give the simple reason: you don't yet know the right boundaries.

for a middle

Should articulate the asymmetric cost of getting a boundary wrong in a monolith versus in deployed services, and know that the recommended starting point is a modular, not tangled, monolith.

for a senior

Should be able to name concrete triggers for when to extract a service, and describe a low-risk extraction approach like the strangler-fig pattern rather than a rewrite.

for a principal

Should be able to identify when the heuristic doesn't apply (known domain, already-independent bounded context) and reference real organizational outcomes to justify the sequencing decision to stakeholders.

## The heuristic The "monolith-first" heuristic, popularized by **Martin Fowler** and **James Lewis** in their writing on microservices, is a sequencing rule for how to build a new system: 1. start with a single, well-structured deployable application (ideally a modular monolith) 2. run it in production long enough to learn where the system's real domain boundaries lie 3. only then extract the pieces that turn out to need independent deployment, scaling, or team ownership into separate services It is explicitly a rule about new, unproven systems — not a blanket claim that monoliths are always better than microservices. ## The cost of being wrong The reasoning comes down to the cost of being wrong about boundaries at two different points in a system's life. Early in a new product, nobody reliably knows where the seams in the domain actually are; requirements shift, the team learns what the product needs to do, and "obvious" module boundaries drawn on day one are frequently wrong once real usage arrives. - **In a monolith, a wrong boundary is cheap to fix**: it's a refactor inside one codebase, executed inside the safety of the compiler and a single test suite, with no data migration across a network and no coordination with another team's release schedule. - **In a microservices architecture, a wrong boundary is expensive to fix**: two services that turn out to be too tightly coupled need their APIs renegotiated, their data potentially re-merged across a network boundary, and their independent deployment pipelines reconciled — all while both are already running in production. Fowler's framing is that you should only pay for microservices' fixed costs once you have evidence, not a guess, about where the boundaries should go. ## What deferring the split costs The trade-off is not free. Deferring the split means accepting, for a while, the coupling costs of a monolith: - a build that grows slower as the codebase grows - a release train that couples unrelated features - a temptation for boundaries to blur without the hard stop of a network call to enforce them — which is why monolith-first is usually paired with building a modular monolith, not an unstructured one It also means later splitting out a service is real work — identify the seam, extract the code behind a stable API, split or replicate the underlying data, and migrate callers, typically using patterns like the **strangler fig** to do it incrementally rather than as a risky rewrite. ## Failure modes on both sides The failure mode on one side is well-documented: teams that go straight to microservices for a brand-new, unproven product often draw service boundaries around their initial (wrong) guess of the domain model, then spend the next year paying network and coordination overhead to work around boundaries that don't match reality — the **"premature microservices"** trap, which frequently produces a distributed monolith (many services, but so tightly coupled they must deploy and scale together) rather than the intended independence. The failure mode on the other side also exists: teams that never revisit the decision once the product and boundaries have actually stabilized, and end up with a large, tangled monolith long past the point where splitting would have paid for itself, usually because nobody enforced module boundaries inside it and "we'll split it later" never had a concrete trigger. ## Where it shows up A widely cited real example is **Segment's** public postmortem of their own microservices migration: they split their core data-pipeline into more than 100 services early on, expecting independent scaling benefits, and later found that most services had highly correlated load and were so interdependent that on-call engineers had to reason about the whole graph anyway — so they consolidated back into a smaller number of services, effectively re-discovering the monolith-first lesson after the fact. Conversely, companies with well-understood, previously-built domains — for example, a team standing up a payments processor that mirrors a bounded context they've operated elsewhere — can reasonably start with a small number of services from day one, because the "we don't yet know the boundaries" assumption underlying monolith-first doesn't hold for them.

  • Does monolith-first mean you should never start with microservices?
    No — it applies specifically when domain boundaries are unproven, such as a brand-new product. If a team already knows the domain well from prior experience, or is splitting off a bounded context that's already operationally independent, starting with a small number of services can be justified from day one.
  • What concrete trigger should tell a team it's time to extract a service out of a monolith-first codebase?
    Common triggers are: a module needs a genuinely different scaling profile than the rest of the app; a specific team needs to deploy that module far more often than the release cadence of the whole monolith allows; or the module's boundary has proven stable across multiple product iterations, meaning the risk of the boundary being wrong has dropped substantially.
  • How would you actually extract a service from a monolith-first codebase without a risky big-bang rewrite?
    The strangler-fig pattern: put a facade or routing layer in front of the functionality being extracted, stand up the new service behind it implementing the same interface, migrate traffic to the new service incrementally, and only remove the old in-process code once the new service has proven itself under real traffic.

It's like not pouring concrete walls in a house until you've lived in a rough floor-plan long enough to know where you actually want the rooms — moving a stud wall is cheap; jackhammering concrete after the fact is not.

saying these in an interview costs you the question

  • Claims monolith-first means microservices are never appropriate at project start
  • Can't explain why a wrong boundary is cheaper to fix inside one codebase than across two deployed services
  • Recommends starting with microservices for every new, unproven product 'for scalability'
  • Doesn't mention that monolith-first assumes the initial monolith is kept modular, not a tangled ball of mud
  • Has no concrete idea of how or when to actually extract a service later

context