We tend to overestimate the effect of a technology in the short run and underestimate the effect in the long run.
In other words, it is easy to understand the gains from a technology, but it takes time to understand its trade-offs. This causes a hype curve as seen below:
Gartner Group considered Microservices in 2017 to be in the “Peak of Inflated Expectations” on Hype Cycle for Application Architecture . Bad news, it seems it’s going to be down the hill from now on. But why? What could be wrong with Microservices?
We spent many years fighting against monoliths plagued with poor code, design and architecture. Monolith applications became associated with big balls of muds : A code no one understands and no one wants to work with.
Martin Fowler in “Semantic Diffusion” , says topics become trendy mainly due to its name. Microservices mean the opposite of big monoliths. Micro versus Big. The first thing it came to my mind was small simple organized pieces. No more monoliths, no more big balls of mud! Also, all the cool companies were doing it.
Microservices started representing everything monolith applications were not, including not having its problems. Most jobs specs have “Microservices”. It makes sense. Would you want to apply to a job to work on a “Monolith”? Microservices became a way of attracting developers.
“Migrating the legacy system to microservices” is bound to cause a huge Semantical Diffusion : an application based on a microservice architecture is not a legacy system. People really believe Microservices can never become a legacy system.
“Legacy conditions refer to a system’s difficulty (or inability) to be maintained, supported or improved.”.
Many people think legacy systems are systems not covered by tests. A system without tests is most likely to become a legacy system quicker. Could a system covered with tests never become a legacy system? There can be high test coverage, but little or none value on them. The test code itself can be a mess, hard to understand and change. Inherently making the system harder to be maintained and improved.
Test coverage and quality are not the only problem in legacy systems. Architecture plays a very important role in it. In a “Big Ball of Mud”  it is described the various phases on software systems degradation, until it eventually becomes a big ball of mud. The most interesting points is it takes time to get there.
What seems simpler: a system running in a single machine (centralized) or spread over the network (distributed)? The complexity of a distributed system is always bigger. Microservices are distributed systems, very distributed, composed of small pieces, micropieces.
Distributed systems, when well design, have many advantages over centralized systems. Including high-availability and scalability. These 2 points should always be the selling point for microservices.
Microservice architecture step-by-step: Break down the problem into little bit of pieces; Write little pieces of software; Spread them over the network; Use technologies to help us out. Couldn’t be simpler.
Have complex problems just become easier to solve? Where all the complexity went? The little pieces of software are so easy to understand, easy to maintain. No way it will become a big ball of mud. If it becomes, we just rewrite the whole thing. It’s so small.
The complexity is not inside the little pieces of software. The complexity is on the division of the problem and connecting pieces. What microservice architecture did was push more complexity into a higher level of abstraction. The big ball of mud will be the whole system together, not the small pieces individually.
Distributed system brought new problems, inherently microservices too. Fortunately we have so plenty technologies today to help deal with them: distributed logging, distributed monitoring, distributed operating systems, containers, container orchestration,… We look to the technology stack and it’s getting bigger and bigger.
For a company new to microservices, the learning curve is really steep. More and more technologies have to be learnt. Make them work together. Do architecture design on top of it. We do many mistakes during the learning process. There is a high probability those mistakes will stay there, in the system.
No one can be a expert in everything. Companies end up with experts in different technologies. To perform a simple task, more and more people have to be involved. Everyone has to talk with everyone and understand each others.
Complexity increase with microservices? Nothing is simpler than calling a method or function on the same machine and on the same process. It comes at a very high cost of complexity and performance to access a different machine. What was a simple invocation, now is a remote call. So many things became involved. So many things can go wrong. So many things to deal with. Using microservices comes with a premium.
One thing I learned the hard way: Don’t learn two things at the same time. Now imagine a company with little experience on microservices (technologies & design), dealing with a whole new domain problem. Many embark on starting with a microservice architecture, but you should be experienced on it.
Small problems fit so perfectly into small and independent teams. Each team gets to work on its own set of services, independently. Worst thing it could ever happen.
Microservices, although physically dispersed, are still very inter-dependent, no matter how low coupling is. Uncle Bob call this “The Decoupling Fallacy” . A feature implementation causes impact on many microservices, across many teams. Change is much harder, because it requires bigger coordination between several dispersed teams.
When we have teams doing their one thing, much of design knowledge gets contained inside the teams. Services become black boxes to outside people. We usually call it silos. Someone might know the overall architecture, but not detailed enough to make decisions required to keep the system architecture clean and organized.
In Agile and Lean development, systems are constantly changing, in directions no one can predict. If you can, than you are not doing it. A strong view and understanding of the current architecture is essential to enable frequent change and refactoring on different levels of abstraction.
This should not be seen as an anti-microservice manifesto. Instead a word of warning when adopting microservices. Technologies, methodologies or approaches don’t solve problems, people do. Microservice architecture should be picked when there is valid reason to do so. Companies should not adopt microservices architectures to get rid of their legacy systems, attract developers, nor to be able to be have more teams working simultaneously.
Good design and architecture are important to avoid software systems becoming legacy. Communication is a key factor. Not only inside the team, but between teams, experts of different technologies, experts from different domains and people who understand the contact points of those domains. Investing time solving structural and organizational problems in a company will eventually be reflected into software design, by Conway’s law. This is how a big ball of mud is avoided or handled.
Big balls of mud will emerge from microservices architectures in due time. Then, as the “Trough of Disillusionment” settles in, you will hear “Microservices are dead”. Hopefully, “Slope of Enlightenment” and the “Plateau of Productivity” will come. One day it becomes something from the past, as it happened with SOA. Some other approaches will appear using the good things from Microservices, but with a different angle and name.
 “Clean Architecture”, Robert C. Martin, 2017
 Monolith First, Martin Fowler
 Don’t start monolith, Stefan Tilkov