Microservices - a significant cost that may not always suit your project
Do you recall the moment when you first heard about microservices? It sounded like a revelation. The promise was sweet and tempting. We were going to break the chains of the monolith that was supposedly slowing us down and enter the promised land, where every service is small, independent, and infinitely scalable. You believed it. I believed it too. The truth is, however, that microservices in the context of small and medium-sized teams are probably the most successful scam in the history of software engineering. It's an architecture that flatters our ambitions, telling us that if we don't manage a constellation of services, we're not really doing ‘serious IT’. It's time to face the truth and admit that instead of solving problems, we've simply replaced method calls with network calls and called this mess architecture.
Scaling chaos instead of product
Let's start with the most commonly repeated myth, which is that monoliths don't scale. This is nonsense that has entered the canon of engineering folklore. What doesn't scale is chaos. What doesn't scale is a lack of discipline in the code and pretending we're Netflix when we're really building a slightly more complex CRUD. Microservices were invented to deal with organisational dysfunction on a planetary scale, where thousands of engineers can no longer work on a single repository. Pushing this model on a team that still fits around one table at lunch or on one Slack channel is technological suicide. Instead of simplifying the system, we are smashing it to pieces and trying to glue the resulting debris together with network protocols.
Losing the superpower of shared context
The biggest advantage of a small team is shared context. This is your superpower. In a well-maintained monolith, every engineer is able to trace the business logic from start to finish – from an HTTP request to a database query. Everyone understands the whole picture. The implementation of microservices immediately destroys this advantage, replacing it with something that could be called ‘distributed ignorance’. No one owns the whole picture anymore. Everyone only owns a small fragment of the system.
Operational farce and cementing mistakes
By choosing microservices, you are not only complicating the code. You are setting yourself up for an operational farce. Each of these small services requires its own CI/CD pipeline, secrets, alerts, metrics, dashboards, and access policies. You no longer ‘deploy’ an application – you synchronise a fleet. A single error now requires an autopsy spread across several services. Implementing new functionality becomes an exercise in coordination between artificial boundaries that we have imposed on ourselves for no apparent reason.
Worse still, microservices ‘cement’ incompetence. In a monolith, flawed architectural assumptions are fixed by refactoring. Moving a model from one module to another is a matter of changing namespaces and a few files. In microservices, flawed assumptions become infrastructure. Bad ideas turn into permanent API contracts that you have to version, monitor, and maintain for years. Instead of flexibility, you get permanent drag.
Back to sanity
Microservices for a small team are not a technical mistake, they are a philosophical mistake. It is a loud statement that the team does not trust itself enough to understand its own system, so it prefers to replace responsibility with protocols. Before you rush into Kubernetes next time and break your domain into ten separate entities, think twice. Monoliths scale great, as long as you have the courage to keep them tidy. Code restructuring is always cheaper than infrastructure restructuring. Maybe it's time to stop ‘process cosplay’ and go back to building software that just works, instead of architecture that only looks good on conference slides.
Happy refactoring!