What is a greener architecture - monoliths or microservices?
Listen to me read this post here (not an AI-generated voice!) or subscribe to the feed in your podcast app.
Like most common rivalries - Liverpool FC and Manchester United, day and night, summer and winter, democracy and autocracy - there is an ever-growing software system architecture rivalry - monoliths and microservices.
One is good for one use case, while the other is better suited for the other. But, what it means when it comes to sustainability? What architecture type is better for designing sustainable, low footprint software? We'll use this article to find out. Sort of...
As in every article I've written so far, we'll tackle the topic with a rather selfish approach - me learning more about monoliths and microservices, and putting them in the context of sustainability.
We'll start first with describing what those architecture types are and what are their main characteristics. After that, we'll explore how they perform when it comes to environment footprint, and what it means for the software we're building. Last but not least, we'll try to give more insights when to choose one or the other.
What is monolithic architecture?
This architecture type is a design that combines all application components into a single, non-separable unit. Putting all layers into one - user interface, business logic, and data access layers.
Key characteristics
Even though this architecture type is not anything new and shiny, it brings some topics that are rather important to consider when designing your software system.
Simplicity. It offers straightforward development and deployment process, easier understanding of the system when the components are packed together. The reason is that we're packing everything in a single codebase.
Cost-effective. These architectures can be more economical for small to medium-sized projects, because they are easy to set up and don't require multiple, separate, components. Therefore, it can be cheaper to start with monolithic architecture.
Performance. The architecture components are closely linked (tight coupling) in a single process and share the same memory space. This adds to often higher performance, because of less (or non-existent) network overhead between the components.
Because of the tight coupling and sharing the same memory space, monolithic applications have limited scalability. Ergo, not easy to scale. This can lead to more performance issues rather than improvements.
On the other hand, having components packed together, reduces the attack surface of the application, making the monoliths potentially more secure.
The structure of the monoliths is often layered - separate layers for data access, business logic, and presentation. Which might result with dependencies across those layers.
The data storage is often centralised - using a single database instance for all data storage needs.
Below, you can find a diagram of a monolithic architecture.
What are microservices?
Microservices are an architecture type of developing software as a collection of small, independent services, that communicate with each other over a network.
Compared to keeping everything in one service in monolithic applications, microservice approach is more for having a separate, loosely coupled, service for each functionality. Each of these microservices can be developed, deployed, and scaled independently.
Key characteristics
Compared to monolithic applications, where you usually have a straight-forward architecture design, microservices have different components based on the design patterns used. I'll not go into details about those patterns here. I will only focus on main characteristics of this architecture type.
Loosely coupled services allow multiple teams to work on different microservices simultaneously, improving the development and deployment cycle. In addition, issues on one microservice usually don't impact others.
This loose coupling allows the system to be scaled more easily, independent of one another. The system can also quickly adapt to changing workloads.
On the other hand, managing service communication, network latency, and data consistency can be a bit difficult. More often than not, it can be complex to develop, test, and deploy the microservices. Network latency can impact services and add complexity to error handling and troubleshooting. Last but not least - maintaining consistent data across services can be challenging.
Below, you can find a diagram of microservices architecture.
What is a greener approach?
Before we provide an answer to the above question, let's have a look at the different lenses we want to look through both of the types.
Resource lens
In order to build more environmentally friendly solutions, we need to have a low resource consumption. That is - CPU and memory. If we have a small project, the resource consumption should be low, therefore, the obvious choice is to start with modular monolith.
However, if we want to introduce scaling to monoliths, then we might end up over-provisioning the application. Giving more resources to all components, even though not all of them need more.
Here, we might want to reconsider microservices - resource usage can be controlled in a fine-grained manner. We can scale up only those services that need scaling. Nothing more, nothing less.
When architecting for greener systems, don't forget that idle applications also consume electricity. Having that in mind can also help us in determining the appropriate type.
With all being said - start small, and build up on that. If your application doesn't require many resources, start with modular monoliths. If properly implemented, it would be easy to later change courses and go for microservices if you actually need them. Don't over-engineer from the start.
Network lens
The second important component that we need to take into consideration is network transmission. The amount of data and overall communication that happens over the network.
Being wrapped in a single binary, service, container, whatever your preference, monoliths have a smaller network footprint. The components within monolith don't need to communicate with one another beyond the localhost. However, reading from and writing data to the database happens over the network. We need to be mindful of that network transmission - how much data are we sending and how often? If it makes sense, we can decrease the amount of read/write operations to bring down the environment footprint even more.
As to overall network footprint of microservices - it is much bigger than the one of the monolithic application. Each service communicates with one another, or with the message queues and database(s), through various network protocols. This communication can be quite extensive. To reduce the footprint, we can do the same as I mentioned above - decrease the amount of read/write operations if possible.
Storage lens
More different storage solutions - more problems. Databases also consume energy. Having the right database solution for your application is often considered a crucial point, not only from the environmentally friendly perspective, but from the overall application performance. Design your database schema and choose DB solution carefully.
Cost lens
Last but not least - how much does this cost? When you start small, if taking the monolithic application road, costs should be small. With the increase in application usage and overall throughput, costs also increase. Having a big modular monolith can introduce more costs in the long run, e.g. when you try to scale it.
On the other hand, microservices will allow you to have more control over what is scaled and what not. But, starting with microservices can be more expensive than having a modular monolith.
The verdict
Before you read the next paragraph, please take a deep breath and try to be in a calm mental state.
There is no straight answer to this question. It really depends, mainly, on your use case and general scalability needs. However, there are some important points to mention.
Modular monolith is easier to handle than microservices. You have one application, compared to multiple. This is a no-brainer.
With low or constant load, monoliths are more energy efficient. The key point here is - low and constant load. In case of a compute-intensive high load, microservices bring more advantages than monoliths.
General recommendation is that you start with a modular monolith. When your application slowly starts to show the signs of Netflix-style scaling, you want to reconsider microservices.
Try not to over-engineer from the beginning and to introduce not used or not needed functionality from the start. This will only increase energy usage of your software, and with it the carbon emissions.
But why do we need to think about energy efficiency of our software when we run the applications on green Cloud providers? Good question. What do you think, what would be the reason? I'll try to add my view of the answer in one of the following articles.
To sum up the discussion - like in all good rivalries, there is no exact winner. The truth is somewhere in the middle.
Shut up, and give me the sources!
This last bit is going to be the place where I give you the follow-up links, research, articles where I found the above-mentioned information.
To learn more about monoliths and microservices
Energy efficiency of monoliths and microservices
This talk was the basis for my research and general information about the energy efficiency of the architecture style. Note, the talk information is in German, but the slides are in English.
Congratulations, you've reached the end of this article! To add your thoughts, use the comment section below. It would be great if you share this, or any other article from my blog, with people that might find them interesting.
See you in the next article!