Architecture Patterns
Loading
Loading
Architecture Patterns
The question is not which is better. It is which problem you currently have.
By the end of this chapter
Separate deployability, independent scaling, fault isolation, and teams that can move without coordinating. Every one of those is real. The last is usually the one that matters most, and it is a statement about people rather than software.
Concept
Microservices trade in-process calls — fast, reliable, atomic, easy to debug — for network calls that are slower, fail independently, cannot be transactional, and require distributed tracing to follow. You pay that continuously. You should be buying something specific with it.
| Monolith | Modular monolith | Microservices | |
|---|---|---|---|
| Deploy | All at once | All at once | Independently |
| Calls | In process | In process | Over the network |
| Transactions | Native | Native | Sagas and compensation |
| Debugging | One stack trace | One stack trace | Distributed tracing |
| Team coupling | High | Moderate | Low |
| Operational load | One thing | One thing | N things |
Enforce module boundaries inside one deployable: each module owns its data, exposes an explicit interface, and reaching into another module's tables is a build error rather than a code review comment.
This captures most of the architectural benefit — clear ownership, independent reasoning, a boundary you could later split along — while calls stay in-process and transactions stay real. It is also the cheapest way to discover whether your boundaries are right, because getting them wrong costs a refactor rather than a migration.
A sound boundary means a typical feature touches one service. If most features require coordinated changes across three, the boundary is wrong — and no amount of tooling will fix that, because the problem is the line, not the plumbing.
Sign in to keep a note here. It is free, and nobody else can see it.
Sign inWhat this chapter was for: