Every few years a team decides the monolith is the problem and proposes a rewrite. Rewrites are seductive because the new system exists only as an idea, and ideas have no legacy edge cases. The finished version always does.
Modularity is about seams, not services
You do not need separate deployments to get most of the benefit. A monolith with genuine internal boundaries, where the billing module cannot reach into the identity module's tables, is easier to work in than a distributed system with none. Draw the seams first. Split processes later, and only where the seam has proven itself.
Where to cut
- Cut where the data is naturally separate. If two areas share a table, they are one module until that changes.
- Cut where teams are separate. Architecture that disagrees with the org chart loses.
- Cut where the change rate differs. A module that ships weekly should not be coupled to one that ships twice a year.
The strangler pattern, applied honestly
Route new work through the new structure while the old path keeps serving. The uncomfortable part is that both exist for months, sometimes years, and someone has to own the duplication. Teams that will not accept that period usually end up with a half-finished migration, which is worse than either endpoint.
Knowing when to stop
Modularisation has diminishing returns. Once deploys are independent and a failure in one area does not take down the others, further splitting mostly adds network calls. Stop there.