Basecamp’s David Heinemeier Hansson has written probably the most readable and balanced dissection of the monolith vs. microservices debate that I’ve run across. Go ahead and read it. A couple choice quotes:
Where things go astray [with microservices] is when people look at, say, Amazon or Google or whoever else might be commanding a fleet of services, and think, hey it works for The Most Successful, I’m sure it’ll work for me too. Bzzzzzzzzt!! Wrong!
DHH goes on to write that
Every time you extract a collaboration between objects to a collaboration between systems, you’re accepting a world of hurt with a myriad of liabilities and failure states. What to do when services are down, how to migrate in concert, and all the pain of running many services in the first place.
...all that pain is worth it when you have no choice. But most people do have a choice, and they do have an alternative. So allow me to present just one such choice: The Majestic Monolith!
The Majestic Monolith that DHH describes is essentially a well-architected (mostly) monolithic application that is well-understood by the individuals working on it.
A point worth highlighting here. A team of about 12 programmers works on the Basecamp application described in this post. That’s not all that much bigger in team size that Amazon’s “two-pizza” team size which, in turn, is often equated with small, bounded context, single function teams that develop individual microservices.
And that’s a key takeaway I think. I’m not sure this is, or should be, a debate about monoliths vs. microservices. Rather, in many cases, it’s a discussion about team coordination. Prematurely optimize into patterns based on tiny discrete services and you silo knowledge and create architectural complexity. Let individual applications grow too large—especially in the absence of of a common vision—and you get brittle and inflexible apps.
Either make components notionally independent of each other (microservices) or you’d better plan on efficiently coordinating changes.