· nervico-team · software-development · 8 min read
Microservices vs Monolith: A Practical Decision Guide
A decision guide for choosing between microservices and monolith: when each approach makes sense, migration patterns, team size implications, and the modular monolith alternative.
Amazon Prime Video reduced its infrastructure costs by 90% by migrating from distributed microservices to a single-process monolith. Twilio Segment collapsed 140 microservices into a single monolith after three full-time engineers spent most of their time fighting fires instead of building features.
These are not arguments against microservices. They are arguments against applying microservices without understanding when they make sense.
The “microservices vs monolith” debate has been generating polarized discussions for years. But reality is not binary. The right decision depends on your team, your domain, your scale, and your business goals. In this guide you will find a practical framework for making that decision.
The Problem with Architectural Dogmas
Why the Microservices Narrative Became Popular
Microservices became the “correct” architecture in the mid-2010s. Netflix, Amazon, Uber, and other large tech companies adopted them and published articles about their advantages. The industry copied them without context.
What was not told:
- Netflix had more than 1,000 engineers when it adopted microservices
- Amazon had scalability problems that 99% of companies will never have
- Uber needed independent teams deploying at different cadences across dozens of cities
These companies adopted microservices because they had specific problems that microservices solved. Most companies that copied them did not have those problems.
The Cost of Following Trends
Implementing microservices when you do not need them adds operational complexity without real benefits:
- A network of services to monitor, deploy, and maintain individually
- Inter-service communication (network, serialization, latency)
- Distributed data consistency (one of the hardest problems in computer science)
- Distributed debugging (tracing an error through 15 services)
- Additional infrastructure: service discovery, API gateways, message queues
If your team has 8 developers and your application has 5,000 users, microservices are probably slowing you down, not speeding you up.
When the Monolith Makes Sense
Small and Medium Teams
The 2025 consensus is clear: microservices benefits only materialize with teams of more than 10 developers. Below that threshold, monoliths consistently perform better.
Why:
- A single repository is easier to understand, navigate, and modify
- A single deployment eliminates the complexity of coordinating multiple services
- Debugging is trivial compared to tracing errors through distributed services
- Refactoring affects the same codebase, not contracts between services
New Projects
You should almost always start with a monolith. The reason: at the beginning you do not know where the natural boundaries of your domain lie. If you split into services too early, you will almost certainly split wrong.
The correct pattern:
- Start with a well-structured monolith
- Identify domain boundaries as the business evolves
- Extract services when there is a concrete reason to do so
- Do not extract services “just in case”
Development Speed Is the Priority
If what you need is iteration speed (startups validating a product, small teams shipping features), the monolith gives you less friction.
You do not have to worry about API versioning between services. You do not need a deployment pipeline per service. You do not have to manage eventual consistency between databases.
When Microservices Make Sense
Large, Autonomous Teams
When you have 50 or more developers divided into teams, microservices enable real autonomy. Each team owns one or more services and can deploy at its own pace.
Signals that you need microservices due to team size:
- Deployment coordination has become a bottleneck
- Teams step on each other’s code continuously
- Merge conflicts are constant and costly
- Testing cycles lengthen because a change in one module affects everything
Independent Scaling Requirements
If different parts of your system have drastically different scalability requirements, microservices let you scale each component independently.
Real example: A streaming system where the video transcoding service needs massive GPUs, but the user profile service runs with minimal resources. Scaling both together in a monolith is wasteful.
Critical Fault Isolation
In systems where a failure in one component must not affect others, microservices provide process isolation.
Example: A payment system where a failure in the notifications module must not affect transaction processing. In a monolith, a memory leak in notifications can bring down the entire system.
Regulatory Requirements
In some industries, regulation requires data or process isolation. Microservices with separate databases make it easier to comply with requirements like GDPR, PCI-DSS, or banking regulations.
The Modular Monolith: The Alternative Nobody Tells You About
What Is a Modular Monolith
A modular monolith is a single deployable with well-defined internal modules and clear boundaries between them. It combines the operational simplicity of the monolith with the internal structure of microservices.
Characteristics:
- Deployed as a single unit
- Modules have well-defined interfaces between them
- Modules do not directly access other modules’ databases
- Communication between modules is via internal interfaces (function calls, not network)
Why It Is the Optimal Choice for Most
For teams of 10 to 50 developers, the modular monolith offers the best of both worlds: clear module boundaries without the operational burden of distribution.
Advantages over the classic monolith:
- Enforced module boundaries (not just conventions)
- Each team can work on its module with minimal interference
- Easier to extract a service if you eventually need to
Advantages over microservices:
- Single deployment
- No network latency between modules
- No distributed data complexity
- Local debugging
Technologies That Support It
Most modern languages and frameworks support modularization patterns:
- Java: Java Modules (JPMS), Spring Modulith
- C#/.NET: Assemblies, separate projects with defined interfaces
- Go: Packages with explicitly defined interfaces
- TypeScript/Node: npm or yarn workspaces, modules with controlled exports
Migration Patterns
From Monolith to Microservices: The Strangler Fig Pattern
The Strangler Fig pattern (introduced by Martin Fowler) is the safest way to gradually migrate from a monolith to microservices.
How it works:
- Identify a feature of the monolith you want to extract
- Build the new service alongside the monolith
- Gradually redirect traffic from the monolith to the new service
- When all traffic goes to the new service, remove that functionality from the monolith
- Repeat for the next feature
Advantages:
- Controlled risk: if the new service fails, the monolith still works
- Incremental progress: you do not need to migrate everything at once
- Continuous learning: each extraction teaches you for the next one
Teams using strangler-fig patterns or domain-by-domain migration achieve 20-30% faster delivery cycles within 6-12 months, according to industry benchmarks.
From Microservices to Monolith: Consolidation
Yes, this also happens. And increasingly so. 42% of organizations that adopted microservices are consolidating services back into larger deployable units.
When consolidation makes sense:
- Operational overhead exceeds the benefits
- The team has shrunk and can no longer maintain so many services
- Latency between services is affecting user-facing performance
- Infrastructure cost is disproportionate to the benefit obtained
How to do it:
- Identify services that always deploy together (they are candidates for merger)
- Identify services with excessive communication between them
- Merge gradually, starting with the most coupled
- Maintain module boundaries even within the resulting monolith
Decision Framework: The Decision Tree
Step 1: Team Size
- Fewer than 10 developers: monolith or modular monolith. No debate.
- 10-50 developers: modular monolith. Consider microservices only if there are specific reasons.
- More than 50 developers: microservices start to justify their operational complexity.
Step 2: System Requirements
Answer these questions:
- Do you need to scale parts of the system independently? If not, monolith.
- Is fault isolation between components critical for the business? If not, monolith.
- Are there regulatory requirements that demand data separation? If not, monolith.
If you answered yes to any, evaluate microservices for those specific components, not for the entire system.
Step 3: Team Maturity
Microservices require competencies that not all teams have:
- Experience with distributed systems
- Ability to design and maintain APIs
- Experience with observability (distributed tracing, monitoring, centralized logging)
- Ability to manage complex infrastructure
If your team does not have these competencies, microservices will slow you down more than they will help.
Step 4: Product Phase
- Idea validation: monolith. Speed is what matters.
- Early growth: modular monolith. Structure without overhead.
- Scaling: evaluate microservices where there is a real need.
- Maturity: hybrid architecture (modular monolith + extracted services where necessary).
Common Mistakes
Mistake 1: Microservices from Day One
Splitting into services before understanding your domain almost always results in incorrect boundaries. Then moving functionality between services is more costly than refactoring a monolith.
Mistake 2: The Nanoservice
A service that does one trivial thing and needs to communicate with 5 other services for any useful operation. The result is high latency, impossible debugging, and complexity without benefit.
Mistake 3: Ignoring Operational Complexity
Every service needs: its own CI/CD, monitoring, alerts, logs, API documentation, version management. Multiply this by 30 services and you have a full-time DevOps team.
Mistake 4: Shared Database Between Services
If your microservices share a database, you do not have microservices. You have a distributed monolith with all the disadvantages of both approaches.
Conclusion
The correct architecture is not the most popular one or the one used by FAANG companies. It is the one that solves the real problems of your team, your product, and your current scale.
Keys to deciding:
- Start with the simplest thing that works. Monolith for small teams, modular monolith for medium teams.
- Do not copy Netflix. Unless you have Netflix’s problems and Netflix’s team.
- Evolve when you have data, not when you have fear. Migrate to microservices when you see real signals, not “just in case.”
- Consider the modular monolith. For most teams, it is the best option.
- If you are already on microservices and it is not working, consolidating is not a failure. It is pragmatism.
Software architecture is a tool, not an identity. Choose the right tool for the problem you have, not for the problem you think you might have.
Not sure what architecture your project needs?
In a free technical audit we can help you:
- Evaluate whether your current architecture is appropriate for your scale
- Identify where architectural complexity is slowing you down
- Design a gradual migration plan if needed
- Define service boundaries based on your actual business domain
No commitments, no PowerPoints. Just an honest technical analysis.