In the last years Microservices gained a lot of attention in the IT. You can get the impression, that Microservices are the new silver bullet. “We can have a Microservice for that”, “Let’s do this with Microservices” or “That system would have been better, if we had implemented it with Microservices” are phrases I hear nowadays very often. Currently, I have a strong Deja vue: it reminds me on the phase, where everybody was “doing agile” but nobody did agile in the right way.
But let’s get one step back: what’s the problem with monoliths?
Monoliths are big. Monoliths can be deployed as a whole only. Monoliths can’t be scaled. That’s what I hear every day. But is that really a problem? No.
The truth about Monoliths
Okay, let’s take a closer look. “Monoliths are big”: yes, that’s true. A monolith is a big monster built by a lot of code. But does this prevent you from organizing your code into modules? Even when your code is living in one repository, even when it’s a single Visual Studio solution (replace with whatever your favourite IDE is), you are always responsible for giving it a meaningful structure. So, I don’t see any reason, why being “big” is a bad thing.
So, let’s take a look one the second argument. “Monoliths can be deployed as a whole only”: that’s true, your code is delivered as a single product. Every small change requires you to deploy the whole thing. The good thing is, that all your DLLs will be installed in the correct version. Every method call will resolve, and your program will be internally consistent. If not, the build would have failed before. This is a very strong argument for monoliths: robustness and integrity! The only drawback ist that small changes result in a complete build run, which may be time consuming. But hey, your build is automated, isn’t it? So, there shouldn’t be any manual overhead for you, it’s just waiting for the build to finish. Again, i don’t see any bad thing here, unless you need a super-fast build and release process.
So far so good. Let’s take a look on “Monoliths can’t be scaled”. Before we argue like this, we need to specify what exactly is meant by “scaling”. Scale up by handling more requests? Being able to handle more network throughput? Faster IO on the database? Having a better user experience? Use more processes, when the user for example searches for something in our application? It’s true that Microservices can be scaled up easily by just starting another 3 or 4 new instances of the desired services. After you have identified, what part of your application needs more resources, just consider this in your code, by utilizing threading or pooling techniques or whatever is needed to accomplish the task. Modern SDKs offer a big number of possibilities to address these issues. Also, the hosting environment might be offering some helpers like a load balancer or a proxy. So, “Monoliths can’t be scaled” is not true, but it has to be considered and implemented by a developer., while the Microservices infrastructure presumably brings this out of the box. Okay, this time the Microservice has scored.
The real problem
So, we discussed some of the common arguments’ pro or contra of the Monolith. But none of them gives us any true reason to simply switch over to a Microservice architecture.
The real problem is not in the Monolith, but in the way we deal with it. There’s one common pitfall, that a Monolith offers us with open arms: shortcutting. The Monolith contains everything: the UI, the business logic, the data access layer and many more. So, what prevents us from accessing the data layer directly from the UI code? Because of “performance reasons”, or whatever argue is needed to justify our decision. The Monolith seduces you to implement one shortcut after the other. There is a significant amount of self-control needed by each developer to do things “the right way”. A well structured architecture of your Monolith can support you in doing the right things, but it will never give you a 100% guarantee, that you aren’t doing it the wrong way.
Microservices do not allow shortcutting. They have a fixed boundary, that you can’t escape. On the other hand, Microservices introduce a zoo of new problems you’ll need to deal with. What about the infrastructure, where the services are running? How do the services communicate with each other? How can you orchestrate the services? Just to name a few.
The real problem is in front of the screen. If you are not able to structure your Monolith, if you don’t get things right here, how can you assume, that Microservices will solve the problems you have?
I can’t give you a general advice towards or against Microservices (or Monoliths). It heavily depends on the requirements, your expectations of the resulting architecture and your experience. If you need flexibility, if you want to run multiple versions of your software in parallel, if you have an infrastructure ready that gives you easy scaling mechanisms and all that kind of stuff, then maybe a Microservice architecture is the right thing for you. If you are not sure about all these conditions and requirements, a Monolith may be the safer decision.
All the best and happy coding 🙂