Ask a room of engineers what a serious, modern backend looks like, and a good number will describe microservices without being asked to justify it. Small independent services, each owning its own data, talking over the network, deployed and scaled separately. It is a real, well-understood pattern that solves real problems. It is also, for most teams reaching for it, a solution to problems they do not have yet, purchased with complexity they will carry for years.
We default to a modular monolith for new products: a single deployable service, internally organised into clearly separated modules with real boundaries, running against one database, one process, one deployment pipeline. The distinction that matters is not monolith versus microservices as a binary choice. It is whether the boundaries between parts of the system are enforced by discipline and code structure, or enforced by the network. A modular monolith can have every bit as much internal separation as a microservices architecture. It just does not pay the network's cost to get it.
The cost that does not show up in the architecture diagram
Microservices make certain problems disappear from any single service's code and reappear, larger, at the level of the whole system. A function call becomes a network call, which means it can now fail in ways a function call cannot: timeouts, partial failures, retries that need to be idempotent or they will double-charge someone's wallet. A transaction that used to be one database commit becomes a distributed transaction, which is either eventually consistent, with all the reasoning that requires, or implemented with a saga pattern, which is its own substantial engineering project sitting on top of the actual product you were trying to build.
None of this is a reason to never use microservices. It is a reason to notice that the cost is real, it is ongoing, and it is paid disproportionately by whoever is on call at 3am when a service that used to be a function call times out for reasons that turn out to be a misconfigured retry policy three hops away. A five-person team building their first version of a product is signing up to carry that cost before they have found out whether the product needs to exist.
Operational burden scales with team size, not ambition
A team of five running fifteen services is not more capable than a team of five running one well-organised service. It is the same team, with its attention divided fifteen ways across deployment pipelines, monitoring dashboards, and inter-service contracts, before a single new feature gets built. Microservices are an organisational pattern as much as a technical one. They let large engineering organisations divide ownership along team boundaries so that fifty engineers are not all editing the same codebase. A small team does not have that coordination problem yet. Adopting the pattern anyway imports its costs without collecting its benefit.
Where we do draw the seams
The reason a modular monolith works as a real long-term architecture, and not just a shortcut for early stage products, is that the internal module boundaries are treated as seriously as they would be if they were network boundaries. Modules communicate through defined interfaces, not by reaching into each other's internals. Where a genuine event happens, a payment settling, an escrow releasing, we publish it through an internal event bus rather than letting one module call another's functions directly. That single decision is what makes the eventual extraction of a module into its own service a refactor instead of a rewrite, if and when that day actually comes.
When it stops being true
The honest answer to "when do you switch" is: when a specific, named problem shows up that a monolith genuinely cannot solve well, not when the codebase starts to feel big. The signals we actually watch for are a component with wildly different scaling needs from the rest of the system, a team boundary that has become a real coordination bottleneck because two teams keep blocking each other in the same codebase, or a compliance requirement that demands physical or network isolation for a specific piece of data. Any one of those is a legitimate reason to extract a service. "Microservices are what serious companies do" is not, and we would rather explain that plainly than build around a diagram that photographs well and costs more than it returns.
Written by
Akintola Stephen Iyanu, founder and engineer at Zynterra. More about the studio.