Microservices: maybe not
Microservices have been gathering some attraction for the past several years for a reason. Microservice-based architecture proved its efficiency and won the hearts of many developers.
But as with any other thing under the sky, microservices is not a silver bullet, it’s a tradeoff. And as with any tradeoff, it’s good to know what you gain and what you lose.
So before you sell your soul to the devil, let’s at least take a quick glimpse into the contract.
The downsides of the microservices
Here the most evident arguments for why forcing the microservices architecture may be a bad thing.
The overall complexity is gonna rise
Compared to a monolith, where you have a single repo and a single database, now imagine you have over 20 repos and you need to make sense of them, like how they interact with each other, what APIs they provide and consume, messaging and so on.
Development time is gonna rise
As a result, now your team is slow. Depending on how good you decouple the components (more on this later), implementing an average feature can require changes in several microservices, which is in my experience is 2x-3x more time comparing to a monolith.
Yes, ideally, microservices aim to solve the performance issues, because every each of them is independently scalable. In practice though, since your data lives in different databases, you have to collect the data from multiple sources. So there’s a network overhead. And don’t forget that can’t use joins now.
Data consistency problems
That’s a flipside to the earlier problem. In order to save some time, you may decide to replicate some data across multiple microservices. Now you’re on the whole different level of complexity. Synchronization fails and the caching problems will make your life a hell.
Forcing decoupling leads to convoluted logic
The problem with decoupling is that you shouldn’t decouple things that are coupled in the real world. One can assume two microservices should be fine on their own and never talk to each other, but in the end, they may (and most probably will) start communicating. Because the requirements have been changed or because there was an implicit connection or any other obscure reason. You never really know upfront. In the end when you try to draw a diagram of what service talks to what, it looks like a convoluted mess.
Newcomer entrance is high
Suddenly you can’t just figure out from the code what’s going on. You now have a set of components each with its own API, and probably some kind of messaging bus. Newcomer unable to simply read the code to see the entire picture. There’s a whole separate bunch of knowledge. That knowledge should be documented somewhere (no one does this), or one would need to read the logs or annoy the coworkers with questions. In practice, it’s usually both.
Last but not the least. Prepare for the quality of your product to decay. In a monolith, you can test everything from tail to head. With microservices, you’re constantly stubbing stuff, and you only test the particular component and its API. But as it usually happens bugs happen on the edges, from miscommunication between the services, which are not tested at all.
So what’s the alternative?
Start with a monolith, extract the microservices when it’s time.
So when to use microservices?
DO: There are performance problems which could be solved by extracting some part of the system and making it separately scalable.
DON’T: You know that your company will be making tons of money soon, and tons of users will create performance issues in the future, and you need to prepare up-front.
DO: You have 30+ developers and you want to have multiple teams with clear responsibility zones.
DON’T: You have 3 developers, who can’t agree on what programming language to use, so you want to let them work on each own’s thing.
DON’T: You want to decouple the logic, and you think that microservices will help with better separation of concerns.
DON’T: You’re a startup.
I’m strongly convinced that everyone should think twice before stepping into the microservices path.
The seemingly benefits turn out to be solutions to non-existing problems. While the downsides are very real and painful.