Two shapes of one system
A monolith ships the whole application as one deployable unit. A microservices architecture splits it into many independently deployable services that talk over the network.
Both can be well or badly designed. The split is about deployment and team boundaries, not about whether the code is modular.
What microservices buy
- Independent deployment so one team ships without coordinating with others.
- Independent scaling of hot components.
- Fault isolation so one service crashing need not take down the rest.
What they cost
- Network calls replace function calls, adding latency, partial failure, and the need for retries.
- Data is split across services, so cross service transactions become distributed and hard.
- Operational overhead grows with tracing, deployment, and versioning across many services.
A sensible default
Start with a well modularized monolith. Split out a service only when a clear pressure appears, such as a component that must scale or deploy on its own, or a team that needs autonomy. Splitting along the wrong boundary creates a distributed monolith with all the cost and none of the benefit.
Let coupling and team structure decide the boundary, not fashion.
Key idea
Monoliths deploy as one unit and stay simple while microservices gain independent deploy and scale at the cost of network complexity, so split only when a real pressure justifies it.