Architecture foundations

4 min read

Monolith vs Microservices: When One Application Wins

A monolith is not automatically technical debt. Here is how to weigh speed, team coordination and operating cost before splitting an application.

Microservices are often proposed before anyone has clearly described the problem they are supposed to solve. The application has grown, releases are getting harder, so it must be time to split it up. Sometimes that helps. Sometimes it turns one difficult problem into ten.

First, find out what is really holding the business back: the application's structure, the way teams work, or the need to coordinate every change with everyone.

One building with connected rooms representing different functions of a monolithic application
Think of a monolith as a building with different departments sharing the same utilities. Working together can be easy; renovating one floor can affect another. It is an analogy, not a software architecture diagram.

One application does not have to mean one tangled mess

Imagine an online store. Catalog, cart, orders and payments can all live inside one application, built and deployed as a unit. That is a simplified picture of a monolith.

Yet its code can still be organised into clean modules with explicit boundaries. A monolith describes primarily how the application is built and deployed, not whether its internals are well designed.

The building analogy helps here. Rooms serve different purposes, but share infrastructure. Good boundaries still matter even when there is only one building.

Why simplicity can win early on

When a product is evolving, future business boundaries are rarely obvious. Today checkout works one way; next month the company tests a different model. A single team and deployment process can make those changes easier.

You do not immediately need to solve all the problems of communication between independently deployed services: network failures, incompatible contracts, cross-service tracing and data coordination. A monolith still needs monitoring and operational discipline. It simply avoids introducing some distributed-system complexity before it is useful.

For an executive, the economics are straightforward: how much engineering effort improves the product, and how much is spent operating the architecture itself? The second category rarely looks impressive on a slide.

Where the cost shows up

Suppose one team owns promotions, another payments and a third customer accounts. When everything ships together, testing and release coordination can become shared work. More teams can mean more waiting.

But a common deployment does not automatically require downtime or endless manual approvals. Release automation, tests and modularity often matter as much as architecture style.

There are technical constraints too. A resource-intensive operation in the same process can affect unrelated functions. Scaling one hot feature independently is less straightforward than scaling a dedicated service. That does not mean monoliths cannot scale: multiple instances of the whole application are often perfectly viable.

Worse is a codebase where changing one area unexpectedly breaks several others. That is a coupling problem. Moving the same poor boundaries into services will not fix it; the dependencies will simply cross a network.

Microservices buy independence, but the bill keeps coming

Separate services can let teams deploy at different times and scale different workloads. In exchange, the company takes on contract compatibility, network failure handling, distributed observability, security between services and harder data consistency problems.

Consider an order saved by one service while another has yet to confirm payment. What does the customer see in between? How do we recover from partial completion? In a monolith using one transactional database, some of these operations can be kept atomic more easily.

So “Why haven't we adopted microservices?” is not a particularly useful management question. A better one is: what independence do we genuinely need enough to pay for it every day?

What I would check before splitting anything

I would start with actual delays. Are releases blocked by the build pipeline? Manual testing? Teams editing the same code? Or approvals unrelated to technology? These are different problems with different remedies.

Then I would see whether internal module boundaries, data ownership, automated tests and a better delivery process could remove the bottleneck. A modular monolith can deliver much of the desired clarity without the full operational cost of distributed services.

A separate service starts to make sense when a capability has a clear owner, a meaningful boundary, distinct scaling or release needs, and someone prepared to operate it. The benefit still needs to exceed the ongoing cost.

When is it time to change?

Persistent release conflicts, proven differences in scaling needs, unacceptable blast radius and changes slowed by shared technical dependencies are serious signals. They justify an architecture review, not an automatic order to break the application apart.

Sometimes the answer is a modular monolith. Sometimes extracting one problematic component is enough. Sometimes a service architecture is justified.

There is no reason to defend a monolith on principle. Keep it while the cost of sharing one application is lower than the cost of independence. Architecture exists to make business change possible, not to prove how modern the engineering department is.