A monolith is not automatically old fashioned, and microservices are not a free architecture upgrade. The useful decision is whether independent services solve a real delivery or scaling constraint that justifies the extra operational work.
01
The modern option is not always the right option
Microservices often enter a software conversation as the ambitious option. They sound scalable, resilient and ready for growth. A monolith can sound like the structure a business should already be planning to escape.
That framing is unhelpful. Both architectures can support serious business software. Both can become difficult when poorly designed. The choice is not between modern and outdated. It is between two different places to carry complexity.
A monolith keeps the application together. That can make development, testing and deployment pleasantly direct, but a growing codebase can eventually make teams queue behind one another. Microservices separate capabilities into independently deployable services. That can give teams and busy parts of the system more freedom, but it also creates a distributed system that must be observed, secured and operated properly.
The right architecture is the smallest one that supports the business, the delivery team and the level of change expected. Anything larger is responsibility bought before it has earned its keep.
02
What monolithic and microservices architecture mean
A monolithic application is delivered as one unit. It may contain customer accounts, permissions, orders, documents, reporting and billing, but those capabilities live inside one application and usually move through one deployment process.
One unit does not have to mean one untidy lump of code. A well designed monolith can have clear modules, deliberate interfaces and strong separation between business areas. The application is deployed together, but developers do not need to mix every responsibility together.
A microservices architecture divides the wider product into separate services built around business capabilities. An identity service might manage accounts and access. A document service might store evidence. A notification service might send messages. Each service can own its code, deployment and data, then communicate through APIs or messages.
That independence is the point. If the services always need changing, testing and releasing together, the architecture has created more projects without creating useful autonomy.
03
Imagine one customer and installer portal
Consider a portal used to register installers, receive customer cases, collect documents, review evidence, issue certificates and pass approved charges to finance. A small product team is building the first useful version and the workflow is still changing as people use it.
As a modular monolith, the team can keep accounts, cases, documents, reviews and finance inside one application. One request can update several related records in one database transaction. A developer can run the whole system locally, follow a case through the code and deploy one tested release.
Splitting the first version into six services would introduce API contracts, service authentication, network calls, deployment pipelines, separate logs and decisions about what happens when one service is unavailable. The business has not removed complexity. It has bought distributed complexity before it knows whether those boundaries are stable.
Now move the example forward. Several teams work on the product. Document processing needs much more computing capacity than the rest of the portal. Notifications are used by other products. Finance releases must follow a different approval route. A fault in certificate generation should not stop installers submitting new cases. Those are real pressures that can make independent services valuable.
04
What a monolith makes easier
A monolith has fewer moving parts. One application can usually be checked out, run, tested and deployed through one route. A business process that crosses several modules remains an in-process call rather than a conversation over a network.
Data changes are also easier to coordinate when the application owns one relational database. If approving a case must create a certificate record and an invoice item together, a normal database transaction can succeed or fail as one operation. The code still needs care, but the consistency model is familiar and visible.
Debugging often begins in one set of logs and follows one request through one process. End to end testing can run against the complete application without assembling a small fleet of dependent services. A smaller team can understand and operate the whole product without maintaining a platform around it.
These are not temporary beginner benefits. They are valuable characteristics. A modular monolith can remain a sensible long term architecture when one team owns the product, releases can move together, scaling needs are broadly similar and the operational cost of separation would outweigh the gain.
05
When one application starts getting in the way
The warning sign is not simply a large number of lines of code. Size matters less than the way change moves through the organisation. A large application can be healthy when its modules are clear and releases remain routine. A smaller application can be painful when every change touches shared tables, hidden dependencies and unrelated tests.
Look for delivery constraints. Several teams may need to coordinate every release because one deployment contains everybody's work. A small change may require a full regression cycle. Ownership may be unclear because any developer can change any part, yet nobody feels responsible for operating a particular capability.
Look for runtime constraints too. One workload may need to scale far beyond the rest of the application. A memory leak in reporting may threaten customer transactions. A long running document job may compete with normal requests. A regulated capability may need stricter access, data handling or release controls than the surrounding product.
Those are better reasons to consider separation than a general ambition to be more cloud native. They identify the specific independence the business is prepared to pay for.
06
What microservices can genuinely buy
A useful microservice gives a team control over one coherent business capability. The team can change, test, deploy and operate it without waiting for an unrelated area of the product. That can shorten release queues when several teams are contributing to the same platform.
Services can also scale independently. If document conversion consumes most of the computing resource, the business can increase capacity there without duplicating the whole portal. A service with a different risk profile can receive its own security controls, deployment checks and recovery plan.
Failure boundaries can improve when they are deliberately designed. A temporary notification failure does not have to stop a case being saved. The application can record the work, retry delivery and show the user an honest status. This requires queues, timeouts, retries and idempotent operations. Merely putting the notification code on another server does not create resilience.
Technology choice can vary between services, but this benefit is easy to overvalue. Allowing every team to choose a different language, database and logging tool can create an expensive support problem. Freedom is useful when a capability has a real technical need, not when variety becomes the architecture strategy.
07
The cost arrives outside the service code
Each service may be smaller, but the complete system is more complicated. A user action can cross several services and networks. One dependency may be slow, another unavailable and a third running a different API version. Partial failure becomes normal enough that the design must expect it.
Data is harder too. Microsoft's architecture guidance notes that each service should own its data, which means one business operation may no longer fit inside one database transaction. Teams need to decide where eventual consistency is acceptable, how failed messages are retried and how people can see work that is still in progress.
Testing changes shape. A service can pass its own tests while the complete journey fails because a contract changed elsewhere. Production support needs centralised logs, metrics and distributed tracing so one request can be followed across the system. Security now covers service identity, encrypted communication, secrets, gateways and more deployed surfaces.
There is organisational cost as well. Independent services need clear owners who can respond when they fail. They need dependable pipelines, common operational standards and enough experienced people to run a distributed system. Without that foundation, microservices can turn one understandable application into a collection of small mysteries.
08
Compare the decision, not the fashion
No single row decides the architecture. The table is useful because it turns a broad technical argument into the conditions the business actually has.
| Decision area | Monolith | Microservices |
|---|---|---|
| Deployment | One release route for the complete application | Independent releases when service boundaries and automation are dependable |
| Team ownership | Works well for one team or closely coordinated teams | Supports autonomous teams that own capabilities from code to production |
| Data consistency | Straightforward transactions across related modules | Service-owned data often requires messages and eventual consistency |
| Scaling | Usually scales the application as one unit | Busy capabilities can scale separately |
| Failure handling | Fewer network boundaries but one process can have a wider blast radius | Failures can be isolated, but partial failure must be designed and observed |
| Testing and debugging | Complete journeys are easier to run and trace locally | Requires contract tests, correlation and distributed tracing |
| Operating cost | Fewer pipelines, deployments and services to support | More infrastructure, automation, monitoring and ownership overhead |
| Best fit | Stable team, evolving product and no proven need for independent operation | Clear domain boundaries, multiple owning teams and valuable independent change |
09
A modular monolith is a deliberate option
The choice is not limited to one tangled application or dozens of tiny services. A modular monolith keeps one deployable application while enforcing useful internal boundaries. Each module owns a coherent responsibility and communicates through deliberate interfaces rather than reaching into every other module's internals.
This gives the team a simpler operating model while the product and domain are still being learned. It also makes future separation more realistic because the boundary is already visible in the code. Martin Fowler's monolith first argument is built around this learning: stable service boundaries are difficult to predict at the beginning, and moving responsibilities between processes is harder than refactoring them inside one application.
Modularity is not a guarantee that extraction will be easy. Shared tables and shortcuts can still create deep coupling. The discipline is to keep ownership clear, prevent modules becoming informal dependencies and observe where change repeatedly crosses the same boundary.
If one capability later earns independence, extract it gradually. Start with a service that has a clear owner, a valuable reason to release or scale separately and a manageable data boundary. Route new work through the service, measure the operational effect and leave the rest of the monolith alone until another boundary earns the same treatment.
10
Choose the responsibility the business can support
Before choosing microservices, ask what must become independent. Is it the release schedule, the owning team, the failure boundary, the scaling profile, the security controls or the technology? If the answer is vague, the architecture is probably being chosen ahead of the problem.
Then test the operating foundation. Can the team deploy services automatically, monitor them centrally, trace a request across boundaries, manage API compatibility and respond when a service fails? If not, that platform work belongs in the estimate. It cannot be wished away with containers.
For many new and mid-sized business systems, a well structured monolith is the sensible starting point. It keeps feedback fast while the workflow and boundaries become clearer. For a larger product with multiple teams and proven needs for independent operation, microservices can justify their cost.
The strongest architecture is not the one with the most services. It is the one that lets the business change safely without carrying more moving parts than the team can responsibly own.
I help established businesses and software teams review application structure, delivery constraints and operational risk before committing to a rebuild or architecture migration. The first useful step is to identify the boundary that is causing real trouble, then decide whether better modularity, a focused extraction or a wider change is actually needed.
Useful questions
Before choosing microservices, ask:
- Which capability genuinely needs to deploy, scale or fail independently?
- Are the business boundaries understood well enough to separate them?
- Will separate teams own each service from development through production support?
- Can the platform provide automated deployment, central logging, metrics and tracing?
- How will data consistency and partial failure work across service boundaries?
- Would a modular monolith remove the current pain with less operational cost?
- Can one proven boundary be extracted gradually instead of rewriting the whole application?
- Who owns the extra infrastructure, security and support responsibility after launch?


