From the Simple to the Complex: Monolith vs. Microservices
Monolith vs. microservices: a long path from a simple structure to a complex architecture.
Join the DZone community and get the full member experience.Join For Free
Working in the software development industry, I often see articles on monolith pros and cons, microservices pros and cons, monolith vs. microservices, etc. — and much less often about the correct transitions between architectural approaches and their interactions. While projects can grow rapidly or dramatically change their course of development, you need to know when and what architectural approach will help support the system.
This article is for those for whom the monolith hasn’t solved problems and only aggravates all processes. It will also come in handy for those who are just getting acquainted with microservices. I will not say which is better, but I will share my experience of migrating from a monolithic to a microservice architecture.
Consider All Risks When Choosing an Approach
Global companies have been using microservices for a long time. For example, monolithic apps from Amazon, Coca-Cola, and Netflix have evolved into larger infrastructures at some point. Brands benefited from this decision and attracted even more audiences. But the trend does not mean the monolith is a thing of the past. The team and I are not used to blindly chasing newfangled trends. We always analyze when this or that option is effective and how it is safer to switch to it.
We worked on a fintech project that was built on a monolith architecture. This approach is like a Rubik's cube: If you take one piece out of it or add other components, the cube will no longer work fully. Each element is a part of a holistic functionality. If a part is missing, broken, or out of place, the one-colored side will not fold.
So why did we choose a monolith? First off, in a startup environment, this type of architecture allows launching a project faster. When, conditionally, in a month it is necessary to present the MVP to the client, but there are no specific requirements or product specifications, only the monolith saves. Its flexibility is reflected in the variety of tools that can be integrated to simplify development. In addition, you can deploy changes or updates all at once rather than individually. Secondly, at the start, the monolith is easy and fast to scale. That is why, for our team, the benefits were clear.
Development of the monolith architecture can be joined by many specialists, including beginners. It is simple and straightforward to use. In a monolith application, all components are interconnected and interdependent. It will be much easier for any beginner to understand the code and logic implemented in the monolith than in microservices.
Our startup has grown rapidly. The number of users and clients grew, and various functionalities were regularly added. After some time, the disadvantages of the monolith appeared. What was critical for us in this aspect:
- Due to the rapid growth of the system, it became more difficult to maintain and develop it without additional resources. First of all, this concerned the cost of making new changes. The further we went and the more features we introduced, the more expensive they became.
- We faced the risk of getting stuck on old technologies in the future. I think many colleagues have come across legacy monoliths — you live in 2021 and deal with code from 2003. It is extremely difficult to rewrite it. Usually, we do not have enough time and resources.
Fortunately, we foresaw the risks in advance, so the transition to the new architecture was not shocking. Everything went smoothly. The microservice approach helped us solve several problems.
- Using microservices multiple times made it easier to adapt to the new requirements of a startup and to scale it. Now we know that to develop an MVP, it is better to use a monolith architecture, and then as the project grows, it is time to migrate to microservices.
- It allowed us to introduce new functionality at no additional cost and simplify the integration of subsequent applications. We are now moving away from strong monolithic cohesion. Most of the functions are divided into small independent groups and are implemented as microservices. Subsequent changes or new features are introduced within such a group or separately as another microservice. This does not affect anything superfluous. What is especially pleasing: There is freedom in the choice of technologies and languages. Each of them has its own advantages.
- It is now possible to use different programming languages for microservices and different types of protocols for communication between them.
But then the shortcomings took over. First, the threshold for joining the project has increased. Second, it has become more difficult to maintain, configure, and test the settings. However, this is not an obvious weakness.
The main thing is that microservices have closed the most important questions. Over time, the client realized that he wanted to sell the product not only as a whole but also in separate parts, thereby making life easier for users. At that time, we already developed various features from which we planned to separate small independent components, and from them to build identical designs or create new business solutions.
The Benefits of Microservices
Each microservice has its own logic and functions, but this puzzle can be integrated into any other system and independently developed. If one of the components stops working, this does not mean that the entire system will necessarily collapse. Perhaps something that is closely related to this microservice will fall off. But in one form or another, the system will continue to work.
The great thing about microservices is that they can be deployed and tested independently of each other. This makes life easier for the team at all stages.
What microservices gave to our project:
- PHP and Golang interaction. They complement each other perfectly and in some cases compensate for each other’s weaknesses. Compared to PHP, Golang can significantly improve performance. Due to parallelism, speed up the processing and execution of certain processes. At the same time, PHP has everything to quickly implement a convenient CRUD.
- Transition from five large clients to more than 20, all thanks to the differentiation of the monolith into separate solutions.
- Optimization of server load. Compared to PHP, Golang uses less memory. With the introduction of Golang into the project and the rewriting of individual parts in Go, it became easier for servers. We no longer face this problem.
- Diversity of the team. Moving to microservices is not only about changing the architecture of the code but also about the team itself. We are divided by areas of responsibility. Once there were five of us; now there are about 40 people. Backend developers and business analysts have been added who are tailored to certain specifications.
There are nuances that complicated the support of transaction security. We are dealing with data decentralization. Also, before creating a code, developers need to be aware of possible inconsistencies.
The changes went not without difficulties for new team members. They need more time to understand how microservices interact with each other and whether they do it at all. How deep should a beginner developer understand this? The deeper the better: the more diverse the knowledge base a specialist has, the more valuable he is on the market and the more quickly he can react to changes in the project.
When there is something to compare with, it is much easier to choose the most suitable option among several others. Therefore, my advice to everyone is to at least familiarize themselves with this architectural approach. A beginner can start with simpler things — a monolith — but remember that someday you will have to delve into microservices. Still, the industry trends have to be considered.
The monolith is like a boiling pot in which a lot of things are cooked at once. Adding new "ingredients", we tried to structure everything. But when stirring this "soup" we affected other "ingredients," even when it was not required. Microservices have helped create a modern technological kitchen and divide the functional areas. We already not only “cooked,” but also “baked”, “boiled”, somewhere “fried”, and somewhere only “warmed up.” Having learned the intricacies of this haute cuisine resulted in quality products.
Monolith or Microservices: Which Is Better?
There is no universal solution nor a final solution. In certain situations, it is more logical to start from a monolith. In the future, the system may reach such a scale that the transition to microservices is inevitable. From personal experience, I have noted a couple of scenarios in which it is worth considering the transition to microservices:
- When, in a monolithic project, the cost of a new functionality does not cover the expected benefit.
- When the project grows to such a size that new people in the team are lost. In microservices, you can take a separate component, determine what is happening in it, and work only with it. In large projects, the separation of duties will sooner or later lead to architectural delineations. Microservices make it easier to relive this moment.
Sometimes, we run into persistent clients who refuse to accept the developers' sound idea. The customer decided to use only this technology or architecture. Why? Because “I saw it on the Internet” or “everyone else does it.” The client rarely thinks about the pitfalls that programmers may stumble upon.
If you see that there is a more effective approach, that the customer's idea will lead to certain problems or stop the development of the project, your task is not to be afraid to tell the client that they are wrong. Explain why it is better to use this or that technology. As practice shows, when you can explain the advantages of your idea and the disadvantages of the solution proposed by the customer, he will calmly take your side. The project is his brainchild, his money, and above all, the client is interested in the efficiency and profitability of the product.
We developed many specifications that existed in isolation and did not fully interact with each other. As soon as we split them into independent microservices, we got high rates in performance and a happy customer who multiplied profits.
My main message is: adapt to the specifics of the project and business objectives. Choose your application architecture carefully (sometimes it’s obvious that there is no contradiction like monolith vs. microservices). The right option will make life easier for you, your team, and your users. And in general, it will make the project more successful.
Opinions expressed by DZone contributors are their own.