Back to Blog
DevelopmentEngineeringArchitecture

In Defence of the Monolith

Microservices are often the answer to a question nobody asked. Here is why starting with a monolith is usually the right call, and what the exceptions actually look like.

EvolRed Team··5 min read

The monolith has a reputation problem. It has become shorthand for legacy, for technical debt, for the thing you replace once you are serious about engineering. This is unfair and, in many cases, actively harmful advice.

Most successful products ran as monoliths for years before any decomposition became necessary. The ones that started with microservices often spent years untangling the complexity they introduced before they had the traffic to justify it.

The Hidden Cost of Premature Distribution

Microservices introduce distributed systems complexity. Network calls instead of function calls. Serialisation and deserialisation everywhere. Service discovery, inter-service authentication, eventual consistency, and the joy of debugging a failure that spans three services and three log streams.

None of this is inherently bad — it is the right tradeoff at the right scale. The problem is when teams introduce that complexity before they have the operational maturity to handle it, the traffic to require it, or the team size to justify splitting ownership.

A monolith is not a single point of failure if it is deployed properly. A monolith is not unmaintainable if it is structured well internally. A monolith that ships features quickly and reliably is doing its job.

When Decomposition Actually Makes Sense

There are genuine cases for moving away from a monolith. When different parts of the system have wildly different scaling requirements. When team size means developers are constantly conflicting in the same codebase. When different components need different deployment cadences or different runtime environments.

These are real problems that microservices genuinely solve. They are also problems that usually arrive at a scale of engineering organisation that most products never reach.

The architecture should follow the problem, not the trend.

The Modular Monolith Is Under-Discussed

The false binary between "monolith" and "microservices" obscures the most pragmatic option: a monolith with strong internal boundaries. Clear module separation, defined interfaces between domains, and a codebase structured so that extraction becomes straightforward when the need actually arises.

This gives you the deployment simplicity and debugging legibility of a monolith, with an internal structure that does not become a big ball of mud. It is the architecture that scales in both directions: easy to operate now, easier to decompose later if you need to.

Start boring. Add complexity when you have a specific problem that complexity solves. The products that succeed long term are built on foundations that worked reliably, not foundations that were impressive in an architecture diagram.


Working through an architecture decision and want a sanity check? Get in touch — we enjoy this kind of conversation and are happy to give you an honest opinion.