
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:
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:
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:
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:
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:
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.