Microservices or Monolith: A Decision Guide for Teams and Products
Microservices are seen as modern, yet for many products a modular monolith is the better choice. How to weigh teams, releases, data consistency and operating costs realistically.

Start with a modular monolith and only extract individual parts as microservices once there is a concrete reason: several teams blocking each other during releases, an area with a significantly different scaling or availability need, or a technically different component. Microservices are not a mark of quality but a tool with noticeable operating costs.
Large platforms show what distributed services can do. But what works for corporations with hundreds of developers is often needlessly complex and expensive to run for a mid-sized product. This article offers a reliable decision guide: a comparison, criteria, common misconceptions and a way to get from a monolith to services step by step.
Two architectures at a glance
A monolith is an application that is built and delivered as a whole. All functions – such as user management, orders and billing – run in one process and usually share a database. With microservices, the application is split into independent services. Each service is responsible for one business area, often has its own data storage and is released independently. Communication runs via interfaces or messages.
In between lies the modular monolith: an application that is run as one unit but is internally divided into clearly delimited modules. The overview below compares it with microservices.
| Criterion | Modular monolith | Microservices |
|---|---|---|
| Deployment | one unit, one build, one rollback | own pipeline and version per service; coordination for cross-cutting changes |
| Data consistency | transactions in one database | distributed data; reconciliation via events, sagas and eventual consistency |
| Scaling | the whole application horizontally; parts not separately | individual services scalable independently |
| Troubleshooting | one stack, one log, one debugger | distributed tracing across several services required |
| Team autonomy | limited: shared code, shared release | high, provided the domain boundaries are stable |
| Operating effort | low to medium | high: more infrastructure, networking, monitoring and security per service |
| Local development | simple | more involved: several services, test data, mocks |
| Suited to | one team or a few teams, products under construction | several independent teams, very different requirements per area |
The monolith is nothing to be ashamed of
A clearly layered monolith with clean module boundaries is the most cost-efficient starting point for many products. There are solid reasons for this:
- Simple deployments: one build, one release, one rollback.
- Traceable transactions: changes across one database stay consistent without distributed coordination.
- Focused troubleshooting: logs, metrics and debugging concentrate on one stack.
- Lower operating effort: less infrastructure, less networking, fewer moving parts.
The word “modular” matters. A monolith without internal structure turns into a hard-to-maintain tangle over time. Even large technology companies have publicly described merging individual services back together because the operating effort outweighed the benefit – a sign that this is not a matter of belief but of weighing trade-offs.
How to keep a monolith modular
- Cut modules by business domain, such as users, orders and billing – not by technical layers
- Allow access to a module only through its defined public interface
- Separate tables or schemas per module and write no queries across module boundaries
- Architecture tests in the pipeline that flag forbidden dependencies – for example with ArchUnit, Deptrac or dependency-cruiser
- Model side effects between modules through internal events instead of direct calls
When microservices make sense
Services play to their strengths when organization and requirements call for it. Software architecture often mirrors the communication structure of the organization (Conway's law). When several teams work on one codebase and must constantly coordinate, a split can relieve them. Typical signs:
- Several teams are supposed to develop and release independently of each other.
- Areas have very different release cycles, for example a pricing module that is adjusted constantly and a CMS front end that rarely changes.
- Individual functions must scale much more than the rest.
- A compute-intensive component needs a different programming language or runtime.
- Domains have different availability and service-level requirements.
The costs of distributed systems
Microservices do not come for free. Distributed transactions require patterns such as sagas or accepting eventual consistency, and messages must be processed idempotently. Network calls bring latency and new sources of error. Monitoring, tracing, service discovery and deployment automation become mandatory. Every interface between services needs a stable contract and versioning – our article on REST APIs with OpenAPI shows how that works. Local development and testing also get harder when several services have to run for one test. Without a mature DevOps practice, a “distributed monolith” quickly emerges: services that can only be changed and released together – with the drawbacks of both worlds.
A rule of thumb from practice: before you carve out services, you should be able to build, test, monitor and roll back a monolith in an automated way. If that does not work there, it will not get easier in a distributed setup.
A decision aid in five questions
- Team structure: Are there several teams that block each other during releases?
- Scaling: Must one part of the system scale independently and much more?
- Service levels: Do domains have different availability requirements?
- Operations: Do you have the skills and tools for distributed systems?
- Domain boundaries: Are the domains stable enough to separate them for good?
If the answer to the first three questions is mostly “no,” a modular monolith is generally the better choice. Question five is the brake on hasty decisions: if you do not yet know the domain boundaries, you will inevitably cut them wrong – and wrongly cut services are more expensive to correct than modules in a monolith.
Three common misconceptions
“Microservices automatically scale better”
Scalability comes from clean architecture, caching and suitable data storage – not from splitting into services alone. A well-built monolith can also be scaled horizontally by running several instances behind a load balancer. How to find bottlenecks before you change the architecture is covered in Cloud scaling for platforms.
“Services will make us faster”
That is only true if teams can actually work independently. If three services have to be changed and released in a coordinated way for every new feature, speed drops instead of rising.
“You can never take a monolith apart again”
With clear module boundaries and the right approach, it is perfectly possible. What matters is that the internal structure is maintained from the start and not sacrificed to deadline pressure.
From monolith to services: the strangler pattern
When the need grows, a module can be extracted deliberately as a service. This step-by-step approach, often called the strangler pattern, lowers the risk considerably because the existing system keeps running while individual parts are replaced. In practice, this sequence has proven itself:
- Choose a candidate: an area with its own scaling, release or availability needs and clearly delimited data, such as image processing, an import service or synchronization for a mobile app.
- Define the interface: specify an API contract or events and first encapsulate the module in the monolith behind this interface.
- Separate the data: own tables or database for the service, with deliberate planning of synchronization. This is usually the most laborious step.
- Redirect traffic gradually: via a proxy or feature flag, running both in parallel at first and comparing results.
- Remove the old code: only once the service runs reliably, delete the original part in the monolith.
How you decide what to tackle first in existing systems also depends on legacy burdens. A method for assessing them is shown in our article Prioritizing technical debt.
Practical examples and checklist
Two scenarios from mid-sized companies
Example 1: customer portal. Suppose a service provider builds a portal with user management, order data, documents, billing and interfaces to third-party systems. A small team develops it as a modular monolith with clear module boundaries. A year later a mobile app with offline capability is added. Its synchronization generates different load peaks and changes more often than the rest. Now a dedicated synchronization service pays off – the rest of the portal remains unchanged.
Example 2: grown industry software. Three teams work on a monolith, releases only happen jointly and require laborious coordination. Here the solution does not start with services but with module boundaries and architecture tests in the existing code. Only once an area – for example price calculation – is cleanly separated and needs its own release rhythm is it extracted using the strangler pattern.
Checklist before you decide
- Business domains and their boundaries are described.
- The team and release structure for the coming years is foreseeable.
- Scaling and availability requirements are known for each area.
- The monolith can be built, tested and rolled back automatically.
- Operational skills for monitoring, tracing and automation are available or planned.
- The total cost of development and operation has been roughly estimated for both variants.
How Nano Concepts can help
For new applications for mid-sized companies – such as portals with user management, data maintenance and interfaces to third-party systems – we generally recommend the modular monolith as a starting point. A standalone service is only worthwhile once an area demonstrably has different requirements. We support you with the architecture decision as part of technology consulting, implement new applications in software development and guide existing systems step by step into a sustainable structure through software modernization. In a free initial consultation, we clarify which architecture fits your team and your goals.
Frequently asked questions
Not inherently. Microservices pay off with several independent teams, very different scaling needs or different service levels. In return, they cause more operating effort, harder troubleshooting and more complex data consistency. For many products, a modular monolith is simpler, faster and cheaper to run.
An application that is built and run as one unit but is internally divided into functionally separate modules with defined interfaces. Modules do not access each other's data directly. This keeps the code understandable, and individual modules can later be extracted as separate services if needed.
When there are concrete reasons: several teams block each other during releases, one area must scale much more or differently, domains need different availability, or a component requires a different technology. In addition, monitoring, tracing and deployment automation must already be in place.
Yes. With the strangler pattern, individual areas are extracted one by one and traffic is redirected gradually while the existing system keeps running. This reduces risk compared with a complete rewrite. The starting point is usually clear module boundaries in the existing code.
That depends on size, data coupling, test coverage and operational maturity. The expensive part is usually not the services themselves but splitting the database, setting up pipelines, monitoring and interface contracts, and the ongoing operation. An architecture assessment provides a reliable basis for an estimate.
Matching services

Software Development
Software from requirements to operations – web, mobile and integrations from a single source.
Learn more
Databases & Cloud
Data architecture, migration and cloud hosting – high-performing, secure and, on request, in German data centers.
Learn more
Technology Consulting
Software selection, architecture, code review and a digitalization roadmap – independent and implementation-oriented.
Learn moreTerms from this article, briefly explained
More articles

Custom Software or Off-the-Shelf? An Honest Comparison
Off-the-shelf tools are quick to roll out; custom software fits exactly. Which solution pays off over three to five years – and why a combination of both is often the best choice.
Read more
Replacing Excel: When a Custom Web App Pays Off
Version chaos, locked files, broken formulas: when Excel hits its limits, which alternatives exist and how the move to a web app with a database succeeds while operations keep running.
Read more
Prioritizing Technical Debt: Pay the Interest or Pay It Down?
Technical debt is not a synonym for bad code – it becomes dangerous when it stays invisible. Here is how to assess legacy burdens by impact and effort and reduce them in a plannable way.
Read more