What is better? Modular Monolith vs Microservices
What is better? This question is quite hard to answer, as most of the developers I could say: “It depends”. I will try to answer based on my own experiences.
Introduction
During the talks inside the IT industry, everyone at least heard about microservices. Microservices have long been a buzzword, even now. Everyone talks about them, everyone loves them, and everyone tries to implement them.
There is even a perception that If you do not have microservices, it usually means that the project is not interesting and simply outdated…
Looks like the IT industry has become enchanted with the idea of microservices, right?
Have you ever wondered why? Where did this sudden interest in microservices and the obsessive desire to implement them come from?
Several things have largely contributed to the popularity of microservices: cloud solutions, containerization mainly thanks to Docker / Kubernetes. A huge number of lectures praising the microservice architecture.
We need to remember that, as with any solution, microservices on one side solve some problems, but bring several others with them. Often much more difficult to tame than the ones we dealt with.
Some of the biggest challenges posed by microservices are, among others:
- Communication between services is complex and hard to maintain (temporary unavailability of the service, API contract maintenance, eventual consistency also can be tricky if not handled properly)
- More services equals to more resources
- Debugging can be very tricky (because of the complexity of the whole architecture, sometimes you will need to debug through a few standalone services to gain information on what is not working properly)
- Microservices can be very costly
- If you are not aware of how microservices should be built, you can create distributed monolith which is the worst thing you can ever have
Let us now consider whether we all really need microservices? The vast majority of companies from the IT industry do not need microservices, they simply do not reach the scale where microservices can show what they can do in all their glory. Here it is mainly about the scale of the system we have, if we are not a company like Netflix, Shopify, etc. We probably will not see any benefits from using microservices also, I think we will only hurt ourselves, in many respects, also financially, because as already I mentioned earlier, microservices can consume a lot of resources, and this results in a lot of money.
What are the alternatives?
Naturally, the first alternative became the monolith, that we all know already. Used for ages, hated by most people, but traditional monolith is not that bad as people think. It is all again a matter of scale. For minor projects developed by small development teams, it is almost perfect architecture.
Monolith Architecture
For simple CRUD systems, MVP, etc., no fancy architecture is needed. But what if we know that our application will grow, we know that the domain we are working on is demanding?
Modular Monolith Architecture comes with the help hand. How is it different from a traditional monolith? And why is it better? First, Modular Monolith is composed of modules. Each module must complete a few requirements.:
- be independent and interchangeable
- have everything necessary to provide desired functionality
- have defined api
Of course, there is no way that each module will be completely independent from the rest of the system, but we have to keep it as independent as it possible. Each module only links to code that it specifically needs.
Modularization is a fundamental change because it allows us to extract each module as a microservice. When our scale will be big enough, then there is no reason to do not extract each module as a microservice to gain all of its scaling benefits.
Compared to the traditional monolith, the modular monolith gives us:
- Reduced complexity
- It’s easier to refactor
- It’s a lot better for teams
In a modular monolith, we treat each module more than a business module than a technical module, which is why it is nicely combined with the idea of Domain Driven Design.
Domain Driven Design in Modular Monolith
Martin Fowler describes it very well in the below quote:
Domain-Driven Design is an approach to software development that centers the development on programming a domain model that has a rich understanding of the processes and rules of a domain.
The name comes from a 2003 book by Eric Evans that describes the approach through a catalog of patterns. I will not enter deeper into DDD because it’s a huge topic to talk about. I want to cover one more thing.
In DDD, we have a term called bounded contexts. It’s all about separating application to business parts related somehow to each other. Following this path, each module in a modular monolith can be treated as a bounded context according to DDD. Thanks to this approach, we gain the well business structured modules which we will extract in the future.
The DDD describes us how business should be divided into the bounded contexts, the Modular Monolith and its modularization tell us how to structure it as a code.
You can find more detailed information about Modular Monolith in the brilliant series of articles made by Kamil Grzybek: http://www.kamilgrzybek.com/design/modular-monolith-primer/
When and why the Modular Monolith is a better choice versus Microservices?
In my experience, the modular monolith is an excellent architecture for most small to medium size projects. To be clear in my understanding, huge size projects are, for example, Netflix, Shopify, etc.
- We maintain modularity similar to the level represented by microservices.
- Communication usually takes place inside the monolith, so it is much simpler than that in microservices
- Savings on resources. We still have a monolith, but modular, so the costs will be much lower than for microservices. In most cases, adding a new module will not cost you a lot.
- Debugging is much easier, mainly because of easier communication between modules.
- The deployment process is much simpler
To sum up, for most companies, a much better choice will be to implement a modular monolith until the scale is larger and microservices make sense.
The above post is of course only my opinion on this subject. Supported by my experiences with all the architectures discussed here.
This is only the start of the bigger series. The next posts will describe my own thoughts about building such Modular Monolith in PHP and how I’m doing it.
Discuss in the comments. I will be happy to get to know other people’s point of view.
Keep watching my newsletter!