The Trouble With Microservices
I recently had lunch with a developer friend who told me about his troubles with Microservices. The company where he was working had rearchitected its monolith-oriented application stack into a modern Microservices Architecture. He told me that the system was composed of over 100 microservices. Some requests coming into the system spawned up to 40 different messages for further processing!
My friend confessed that his initial excitement of working with microservices had cooled. Debugging the system was quite challenging—there was no option to run the application on his machine. The developers had to do their debugging from a production-like environment. Determining which path a problematic request took between multiple instances of the same service proved frustrating too. Finally, the different microservices’ independence surfaced as a liability when developers changed message definitions without communicating those modifications to other teams, breaking the system.
And how many requests came into this microservices system per day? 100 million? No, fewer. 100 Thousand? Fewer. 100? Yes, 100. At most. The average day had around 60 requests!
My developer friend thought the system had been willfully over-engineered. Microservices are great for extreme scaling. Suppose I needed a system that can handle tens of millions of operations per day—here I might consider a Microservices Architecture.
However, systems don’t start out processing millions of messages per day. They begin by handling relatively few requests—like 60 per day. In my friend’s company, the technical decisionmakers knew before starting on the rearchitecting project that the daily throughput would be very low. So why do it?
Because the Microservices Architecture is riding high right now. Many architects and developers perceive it as the solution for all our system ills. That is not the case. Unless you need extreme scalability and throughput, I recommend you shun Microservices.
If you’ve designed your system well—partitioned it into cohesive modules and sensible components—then it should be relatively simple to move from a single process executable (aka Monolith) to Microservices. As the system’s load increases, you could reconfigure the monolith’s components into a hybrid arrangement of scaled-out distributed services across multiple machines communicating via queues. Once the system is straining under further increases in load, you finally move to the Microservices Architecture.
That is what a great architecture allows you to do—choose a suitable deployment model for your system without having to alter the constituent parts—components and modules.
We’ll drill more into Microservices and how they differ from Monoliths another time.
 Microservices Architecture is a misnomer—it’s not an Architecture; it’s a Deployment Model.