The Problem: There are many issues with Microservices. Complexity, skills, knowledge and management are some of those. Not every architecture needs to be broken down into discrete micro-service patterns. It depends on the project, use cases and 100 other factors. There is often a very real cost to microservices – reduced performance, issues with operations, and exploding infrastructure costs.
Don’t be a sheeple and follow the pack. Build an architecture that is manageable, cost effective, performant and sensible, which maps to your real use cases, user and data volume, skills and budgets.
Figure Saint Micro of the Services:

A ) Issues with Saint Micro of the Services
In summary when you delve into microservice deployments you may encounter the following:
- Increased latency
- Open db connections
- Slow deployments
- 50-100% increase in infra costs
- Reduced developer velocity
The above will depend on the number of services and the absolute volume of data and end users.
1 ) Operational costs
At scale there are some obvious complexities, especially around operations and raw overhead:
- API contracts
- CI/CD pipelines
- Deployment coordination
- Observability tooling
- Retry logic and circuit breakers
Building and managing containers is a non-trivial task. Docker skills are not legion. Kubernetes knowledge thin. Most likely you will be forced into an MSP or Managed container offering in AWS or Azure. This can be costly.
Consider: If you have a reasonably ‘simple’ system composed of 10-12 microservices, the number of inter-service failure points will explode. How will you manage this?
2 ) Network Overhead and Latency
Single user process flow and hops:
[Gateway] –> [Auth Service] –> [User Profile Service] –> [Subscription Service] –> [Payment Service]
Each hop adds:
- Network latency
- Serialization/deserialization
- Distributed transactions are a real pain
- Security checks
- Potential retries on failure
Under a heavy load, the above overhead becomes non-trivial. Given that each service has its own independent database, a service that needs data from another service has to make a network call to that service’s API. This introduces latency, potential network failures, and the overhead of data serialization and deserialization. This is a real pain point with Saint Micro.
B ) Modu-Liths
Not the usual mixed up, entwined monolith, but a modularised monolith or Modu-Lith, with well defined modules, layers, and internal APIs which denote service boundaries, but eschew the network overhead. There is nothing wrong with such an architecture and it resembles the Strangler-Fig migration pattern if one is migrating from on-premise to the Cloud.
Figure Modulith:

This diagram shows how a modular monolith is structured. The key ideas are:
- Internal Modularity: The monolithic application is divided into distinct, independent modules (e.g., Payments, Reporting, User Management).
- Well-Defined Boundaries: Each module has a clear boundary and communicates with other modules through well-defined internal APIs, not direct function calls. This is achieved via ‘Package Level’ boundaries.
- Package level boundaries: These reside at the package or namespace level, where you get many of the benefits of microservices (decoupling, clear ownership, independent development) without the operational overhead of deploying and managing multiple separate services.
- Shared Core: A central ‘Core’ module handles shared concerns and orchestrates interactions.
- External Interaction: Modules can still interact with external services, just like a microservice would.
- Comms: Modules communicate using in-memory function calls, which are extremely fast because they happen within the same process. This significantly reduces latency and overhead compared to a microservices architecture.
Trade-off: The main trade off is that with function calls, and a shared core, a Modu-Lith cannot scale its modules independently. There is no real ‘independence’ of modules as there is with a micro-services approach. There is, however, a clear boundary between the modules.
In essence each module (Payments for eg) would have its own models and services and communicate with other modules via clearly separated interfaces. The modules do not share database tables.
This architecture allows for a gradual, controlled migration to a microservices architecture, if that is the intended future target. Akin to the Strangler Fig migration pattern. It supports a heavy load, can scale and is more easily manageable.
Figure: Strangler-Fig pattern

You can also have direct function calls. This reduces the use of HTTP and JSON. This means that the module boundaries have function interfaces with a dependency injection. This will increase performance and reduce latency.
Bottom Line – Don’t use Saint Micro of the Services when:
- You have a small team or small application volume (<1000 end users)
- Scalability is not a primary concern (stable, flat usage patterns, no you are probably not Netflix or LinkedIn and don’t pretend you are)
- The application needs very strong consistency
- The firm does not have multiple development teams with full autonomy
- You have little or no skills with Docker or Kubernetes
- You don’t have the infra budget or the ability to hire a full platform SME/team
The Modu-lith has its advantages and disadvantages. It may or may not be suitable for every use case. However, it does provide a common-sense approach to building more robust and scalable architectures without the costs and complexity of a full microservices architecture. As with most things in life, use your common sense and map the architecture to the reality of the application, end user volume and use cases, data volume and your skills, budget and time-frames. No need to be a sheeple.
https://www.linkedin.com/pulse/modu-liths-vs-microservices-craig-f-r-read-g3nte