Das falsche Entweder-oder
Monolith und Microservices sind nicht die einzigen Optionen - und Microservices zu früh zu wählen erkauft verteilten Schmerz für Probleme, die man nicht hat. Der verteilte Monolith, das Schlechteste aus beidem.
Deutsche Übersetzung in Arbeit
Diese Lektion ist noch nicht ins Deutsche übersetzt und wird daher auf Englisch angezeigt. Der Rest der Seite ist vollständig lokalisiert.
Auf dieser Seite
"Should we build a monolith or microservices?" is one of the most consequential - and most botched - architectural questions. It's usually posed as a binary between a big ball of mud and a fleet of tiny services, and teams reach for microservices to feel modern, inheriting a mountain of distributed-systems complexity to solve problems they don't have. The truth: there's a powerful middle option, and the right default for most teams is not microservices.
The false binary
The question assumes two choices. There are at least three:
- The "big ball of mud" monolith - one deployable, no internal structure, everything tangled. This is what
people mean by "monolith" when they disparage it (and what
ledger-legacyis). - Microservices - many independently deployable services, each its own process and database, communicating over the network.
- The modular monolith - one deployable, but internally split into well-bounded modules with enforced boundaries. The structure of microservices, the simplicity of a single process.
The disparaged "monolith" is really the unstructured monolith. A modular monolith gets you clean boundaries without the distributed tax - and it's the subject of this whole module.
What microservices actually cost
Microservices solve real problems - independent scaling, independent deployment, team autonomy at large scale - but they're not free. Splitting a process into networked services buys you:
- Distributed systems, everywhere. Every in-process method call becomes a network call that can be slow, fail, or time out. You now need retries, circuit breakers, and idempotency (recall the Spring Cloud module).
- No more ACID transactions across services. A change spanning two services can't be one transaction; you're into sagas and eventual consistency for things that were trivially atomic before.
- Operational overhead. Many deployables to build, deploy, monitor, and trace; service discovery, an API gateway, distributed tracing - all now mandatory, not optional.
- Hard-to-move boundaries. Get a service boundary wrong and fixing it means coordinating changes across network-separated, independently deployed codebases - far harder than moving a method between packages.
That last point is decisive: you rarely get boundaries right the first time, and in a monolith they're cheap to move. In microservices they're set in concrete.
The distributed monolith: the worst of both
The most common failure is landing in neither good option but the trap between them: a distributed monolith - services that are split across the network but still tightly coupled, so you can't deploy one without the others, and a single request fans out through five of them. You've paid microservices' full operational cost and kept the monolith's coupling, gaining nothing. It usually happens when a team splits into services before understanding the domain's boundaries - splitting by technical layer or premature guesswork instead of real seams.
Start with a modular monolith - almost always
The pragmatic default, championed by many senior engineers, is: begin with a modular monolith, get the module boundaries right in a codebase where they're cheap to move, and extract a module into a service only when a concrete pressure demands it (a module needs independent scaling, a separate team must own its release, or a distinct tech stack is required). Microservices are a solution to organizational and scaling problems, not a starting architecture. Don't take on distributed systems until the problem is distributed.
A big-ball-of-mud monolith is a single room where every team works at one giant shared desk, papers intermingled
- chaos. Microservices are a sprawling campus of separate buildings across a city: each team gets autonomy, but now every conversation is a scheduled video call that can drop, you can't just lean over to ask a question, and moving a team to a different building is a construction project. The modular monolith is one building with clearly separated, walled offices: teams have their own space and boundaries, yet collaboration is a walk down the hall (an in-process call), and you can rearrange the walls over a weekend. You only build the separate campus when a team genuinely needs to be in another city - not by default.
A 6-person startup is building a new product. Their CTO, excited by a conference talk, proposes launching with 12 microservices - separate services for users, billing, notifications, catalog, etc. - each with its own database and deployment pipeline. The domain is new and still shifting weekly. What's the risk, and what would you recommend instead?
What is a 'distributed monolith' and why is it the worst outcome?
Key takeaways
- The monolith-vs-microservices question is a false binary: the modular monolith (one deployable, enforced internal boundaries) is a third, often-best option.
- The disparaged 'monolith' is the unstructured big ball of mud; a modular monolith gets clean boundaries without the distributed tax.
- Microservices cost real complexity: network calls that fail, no cross-service ACID transactions, heavy operational overhead, and boundaries that are expensive to move.
- The distributed monolith - networked but tightly coupled services - is the worst outcome, paying microservices' cost while keeping the monolith's coupling.
- The pragmatic default is to start with a modular monolith and extract services only when a concrete scaling, team, or deployment pressure demands it.