When microservices migration doesn’t make sense
October 5, 2020 • 6 min read
While microservices architecture is a great way to design modern systems, most enterprise applications are still built as monoliths. While working with both Fortune-1000 companies and startups we often hear the same three questions:
- Should I use microservices architecture for the new system I am building?
- Should I migrate an existing monolith to microservices?
- How “micro” should I go when going with microservices architecture?
Although the exact answer to each question depends on the specifics of each case, in this article we will provide answers to some of these questions and describe when it doesn’t make sense to implement or migrate to microservices architecture. In this article, we intentionally avoid technical details and focus on the management side of the issue.
The benefits of microservices
Before we answer the main question of this article, we would like to analyze what benefits and value microservices can bring to a company. Roughly speaking, microservices architecture helps address the problem of scale. The problem of scale, in turn, can manifest itself in two main ways at a high level:
- Size of a development team – this is measured as the total number of analysts, architects, developers, test engineers, deployment engineers, and other team members that contribute to the implementation of the system.
- Lifespan of a system – this is measured in the number of years the system has been in place and how much longer it will continue to be actively developed.
The first is the “space” dimension of scale, while the second is the “time” dimension. Notice that we do not mention the volume of code, number of features, or complexity of the functionality here. All of these factors are derivative from the first two and don’t directly influence the architectural decision.
There are two management know-hows that explain the value of microservices in addressing the “space” scale problem:
- The optimal number of people in a team ranges from 5 to 12, which is proven by management science and in an informal “two-pizza team” rule.
- “Any organization that designs a system will produce a design whose structure is a copy of the organization’s communication structure”, which is known as Conway’s Law.
When an organization needs to implement a large system, and especially when it needs to do it quickly, it will have to scale to tens, hundreds, or even thousands of engineers. To make those engineers productive, an organization will need to split them into “two-pizza” teams.
In order for these teams to maintain high output and deliver large numbers of features over a period of time, they will need to work with some degree of independence and isolation. And the best way to do it is to split the whole system into services with very well defined contracts and APIs. To ensure high levels of productivity, the release process will have to support independent releases of these services, and the entire source code management and CICD will have to provide a good degree of independence. We spoke about designing such a release process in one of our previous articles.
Understanding the underlying principles of solving the “space” scale problem with microservices gives a partial answer to the questions of when to use the microservices architecture and how micro to go. Different organizations can get to the problem of scale in different ways. Some will start big and will have to design the system for scale. Some will start small and will scale gradually. The latter ones will often find themselves working on a large monolithic codebase and face challenges with deteriorating productivity and observe diminishing returns when scaling the team beyond a certain size.
Microservices architecture in small teams
What if the size of the team is small and will likely stay small for a long period of time? The single teams or even single developers trying to implement microservices architecture will often find themselves in this situation when formally they have used microservices architecture, but they:
- Don’t maintain backward compatibility of API contracts because it is easier to fix both the service and the client when a new change is introduced instead of keeping backward compatibility.
- Have shared libraries where each change results in rebuilding and releasing most microservices or applications. The teams or individual engineers often do it for efficiency to avoid potential duplication of functionality.
- Have most of the testing implemented as integration tests on a UI level because it is easier to implement and maintain it over a short period of time.
- Use a monolithic release process because it is more convenient.
It is hard to blame the team when it happens. Microservices architecture brings inefficiencies, and good developers hate inefficiency. When you and your teammates know the entire system and communicate often, the team will gravitate towards a monolith. In large-scale environments with multiple teams, creation of shared libraries and negotiation of API changes gets difficult, because of an overhead on human-to-human communication.
In this case, does it make sense to implement microservices architecture and have several truly “micro” services per team or per developer? To answer this question, we should look at the second aspect of the problem of scale – the “time” dimension. If a system will be actively developed for many years, there will be times when parts of the system will need to be rewritten. There are many reasons for this:
- Some features will become deprecated
- New features will need to be added
- Old technologies will become obsolete and will require replacement
- New SaaS offerings or 3rd party products will be available
- The team will want to compare old and new features with A/B testing
If a system is designed as a monolith with a lack of APIs and well-defined contracts it will be difficult to replace one part of the system with a new one, remove and retire a part of the system, or add a new feature. So microservices architecture is useful to address the “time” dimension of scale. However, in this case it may not make sense to invest into independent CICD and retain a monolithic release process.
When it doesn’t make sense to migrate
Looking at the benefits that microservices architecture and release processes provide, and the problems of scale they help address along dimensions of “space” and “time”, we can now summarize when it does and doesn’t make sense to implement or migrate to microservices architecture.
It usually doesn’t make sense to migrate to microservices architecture when you don’t have scalability problems in both “space” and “time” dimensions. Practically speaking, it means that migration doesn’t make sense when you do not expect new massive feature development or growth of the system. Even if the existing team is large, but the development is expected to stay at the current level or to decrease, migration may bring more challenges than solve problems due to the changes in the culture, process, skills, and technologies required. The only reason why you may consider migration in this case is if the productivity of the team is very low and keeps degrading, and while the development won’t grow dramatically, it will stay large for a long time.
When considering a new development, it makes sense to start with microservices architecture in almost every case, with the exception of small applications that will not be developed for a long period of time. In case development is expected to continue for a long time, but the team is expected to stay small as well, it makes sense to invest in microservices architecture but keep the monolithic release process.
Conclusion
Microservices architecture is an excellent tool to address organizational scalability and development longevity problems in software engineering. However, it brings its own inefficiencies and can be avoided if an organization doesn’t have scalability and productivity problems. Small teams can be productive with monolithic release processes, and small short-lived applications can be implemented cheaply and efficiently with monolithic architecture. Feel free to reach out to us to learn more about how to solve organizational scalability and efficiency problems with microservices architecture and a continuous delivery process.