“The goal of software architecture is to minimize the human resources required to build and maintain the required system.”
Robert C. Martin
In the last 5 years, before the start of a new project, microservices have been pretty much the topic on every architectural conversation. The idea is great, small, independent, cohesive, services that can be implemented, tested, maintained and released individually without much impact on the rest of the system. Microservices are then the holy grail of architectures all positives and almost zero negatives. If that is the case, why in the last 2-3 years our holy grail is getting bad press? Some engineers even suggest that a monolith is better. I am sensing the anger in you while reading this blog, asking yourselves how can a monolith be better? Well, it all comes down to pros and cons and how the business is structured.
Let’s start with the structure of the business, microservices are independent and cohesive which means that a team can develop services in silos and do not need to coordinate extensively with other teams since there are no dependencies. The teams can pick their programming language, databases, CI/CD process etc. Why I am saying all these? Apart from the word silo everything else sounds great and you have already found solutions for the silo-like documentation, service discovery, controlling what technology to be used etc… Regardless of your solutions, the uniqueness of the service will require the original team to change and maintain it since they will be more effective. You cannot have everyone in a department to be experts in every programming language and database system. If we accept that each service is a silo then each team needs to maintain that service for life, which brings us back to the business model, do you accept the cost that each team will be maintaining a service for life? In a youtube video, the VP of Spotify said they have 500 teams and 750 services which validates what I just described.
So, let’s say that you work for the new Spotify/Netflix and you have the funds to assign up to 2 services per team. What are the pros then?
- Independent deployments are simple, each service can be built and deployed in isolation and if it has zero dependencies it can be even tested.
- Fault isolation can be achieved since the services are independent.
- The focused teams can build domain knowledge and have a good understanding of the codebase since they have specialized in a very specific area.
- Engineering freedom each team can pick any technology out there.
- The Code surface area can be expanded easily which means a department can be scaled as the company grows.
But there is no such thing as a free lunch, so what are the cons.
- Simple Mathematics, if the ratio of services over teams is not balanced then the software development will become unsustainable.
- Small tasks feel gigantic, let’s assume that you need to change your monitoring/auth provider or add a step in your CI/CD with microservices you will need to repeat the same task multiple times.
- The Complexity of the system is only kept in control by the number of teams that you have. Which means if the business is not growing as fast the complexity of the system will grow exponentially.
- Impossible to outsource since the new teams are only for a short time, that means the ownership of their services would need to be absorbed by existing teams, which will add additional load since the outsource teams may have used a brand new tech stack.
- Impossible refactoring since each service is in its own repository and the modern tools mainly work on a single repository. Which means great news, grep and the 1980’s tools are back.
- DRY is less likely to be applied.
- Network latency exists even with the big cloud providers, if a client request, needs lets say 10 internal requests and for every request you will need atleast 100ms then those small delays starts to add up.
- Team skills will be a challenge since a highly distributed system would be more complex. Be prepared to compete and pay for the best of the best.
- Security will be hard to apply since the system has a high degree of entropy.
At this point if you still believe microservices are the way forward, here are some Microservices smells so they can be addressed before they become an issue.
- The teams do not understand and do not own the business domain.
- There are more services than teams.
- There are more repos than teams.
- Services talk to each other extensively (even through a messaging bus).
- Services share data storages.
- APIs are not consistent.
- Failures are not detected in critical systems.
- Lack of containers.
- Lack of standards (versions, languages, frameworks etc.)
- Cross-cutting concerns have to be implemented for every service.
- Services are not idempotent.
I would love the idea of getting all these smells right from day 1 but unfortunately, microservices are by far the most challenging and costly architecture, my advice at this point is to ask:
- Do you need a highly distributed system?
- Can you do a monolith first?
- Is there a better compromise like
- Is N-Tier architecture a better approach?
Microservices architecture on paper sounds amazing but unless the business as a whole is not committed to it, then your department will end up with low morale, low productivity, and tones of code debt.