Quick summary: In this article, we will compare microservices and monolith architecture, discuss what teams and projects should use what type of architecture, and explore their advantages and disadvantages. Exploring the opposite and similar worlds of both concepts. Consider it a written podcast. 😊
The constant evolution of technologies has always kept us in frequent change of the way we build the architecture of our applications. Docker, Cloud services, Container Orchestration and futuristic services has given us ability to develop distributed, more scalable, and reliable solutions. Each has its merit above against other, and not leaving out its flaws also.
What are microservices architecture?
According to official documentation, Microservices — also known as the microservice architecture — is an architectural style that structures an application as a collection of services that are
- Highly maintainable and testable
- Loosely coupled
- Independently deployable
- Organized around business capabilities
- Owned by a small team
The microservice architecture enables the rapid, frequent and reliable delivery of large, complex applications. It also enables an organization to evolve its technology stack. Breaking your complex application into separate blocks of services that when put together makes a whole application.
What are monolith architecture?
Monolith simply refers to one block containing all in one piece. According to Wikipedia, a monolithic application describes a single-tiered software application in which the user interface and data access code are combined into a single program from a single platform.
Great. With the two definition cleared out, we can now discuss the different aspects of comparison between the two architecture. The pros and cons, the right one for the project and the team.
The architectural design of monolith application allows that we set our deployment once and adjust it based on ongoing changes. But there is also only a single point of failure during deployment and, if everything goes wrong, we could break our entire project.
The architectural design of microservices require more work — we will need to deploy each microservice independently, put into consideration the orchestration tools, and also try to unify the format of our CI/CD pipelines to reduce the amount of time required for doing it for each new microservice.
There is a bright side, however — if one of the microservices goes wrong, we would only break one small microservice, which is less problematic than the entire project. It’s also much easier to rollback one small microservice than an entire monolith application.
Monolith applications are always hard to scale horizontally. For instance, when we run more workers for our project, every worker available will be on the single — whole project. This is absolutely an inefficient approach to using resources. Vertical scalability would be possible for our code but renders the horizontal scalability impossible.
Scalability on the microservices architectures are again better suited. Resources can be used more carefully and allows us to scale only the parts that require more resources.
Cost is always tricky to determine because monolith architecture is cheaper in some scenarios, but not in others. With a small monolith app, we could run on a $5-$20 host and turn on the snapshot. On a larger monolith app, we may host a very expensive instance because we can’t share it over multiple small, cheap hosts.
With the better scalability of microservices, we could set up an auto-scale and only pay for that when the volume of users really requires more resources. But remember that to keep this infrastructure up and running, we will need a DevOps that would be paid, more cost.
Maintenance for microservices architecture requires DevOps for the team or we prepare ourselves. There’s a need for someone to monitor and maintain the functioning state of our CI configuration for each microservice and the whole infrastructure. But not all developers will have adequate knowledge on Docker or orchestration tools, such as Kubernetes, Docker Swarm, Mesosphere, or other similar tools that would help us to manage infrastructure with a lot of moving parts.
Maintenance for monolithic applications only gets demanding if the application is too large and complex to understand entirely. Simply because it is quite challenging to make changes fast and most importantly, the right changes.
The independent nature of the microservices architecture makes it our obvious winner here. When one of the microservice is affected, only that part and the user that uses it is affected no one else.
But this is a different case on the monolithic applicaton. For example, we’re building an e-commerce app and the microservice responsible for paying for our items on the cart is down, this is definitely serious, the whole app will be forced to stop.
The higher the microservices are being added to our project, the more complex or better said, trickly it becomes to manange them all. The best approach to dealing with this complexity on microservices, would be to build our docker-compose file from the very beginning leveraging on Docker for during development. This would helps us reduce the timeframe to be spent when onboarding new developers — simply run the system from scratch and launch all available microservices as needed. Opening many terminal windows to execute commands to start each individual service is a pain.
Then in the case when we have only one microservice, we may may need to run other parts of the application at all. This means fewer problems on git conflicts due to well broken down tasks, and the unrestricted ability to isolate our developers across microservices. This is better code review, and the QA part is simpler with microservices.
There’s no explicit support for developing distributed applications when working with monolith architecture.
New features are released faster on microservices that are smaller and with a proper architecture of microservices communication. This means a well reduced QA time, build time, and tests execution time.
Monolith applications have a lot of internal dependencies that cannot be broken up. There is also higher risk that something we are committed to could depend on unfinished changes from a team member, postponing the releases.
What’s architecture better to you?
Here we will list out opinions, both ours and other software engineers who have worked with these architectures.
Use monolith architecture if we:
- have a small team.
- build the MVP version of a new product.
- did not get millions in investments to hire DevOps or spend extra time on complex architecture.
- have experience of development on solid frameworks, such as Ruby on Rails, Laravel, etc.
- don’t see performance bottlenecks for some key functionality.
- think that microservices are cool and it’s a trend.
Keep in mind that if we find out that there is need of microservices in our project, monolith architecture always carries the risk of break down as a result of these small microservices.
Use microservices architecture if we:
- don’t have a tight deadline; microservices requires us to research and architecture plans to ensure it works.
- have a team with knowledge of different languages.
- worry a lot about the scalability and reliability of our product.
- potentially have a few development departments(maybe even in different countries/time zones).
- have an existing monolith app and see problems with parts of our application that could be split across multiple microservices.
Choosing what architecture to work with determines what fast and scalability during development means to the project after weighing the pros and cons of each factor. The nature of the application, its different parts and the requirements needed for it. In most times, a monolithic approach is best suit for a lightweight application. And a common recommendation is to adopt monolithic approach first as the requirements gradually increases, then the shift towards microservices approach.