Docs

Documentation versions (currently viewingVaadin 24)

Monoliths

Essential concepts, as well as advantages and disadvantages of developing and using monolithic applications.

In software engineering, a monolithic application is a single, self-contained application. All system components run inside the same executable and communicate with each other over function calls. The application typically provides a single but complete service to its users.

Although a monolith often requires some supporting services like a database or an authentication provider, it’s quite self-sufficient. In its simplest form, a monolithic application is a single executable that runs on a single server.

Even though monoliths are packaged as a single executable, they can still be modular. Modular monoliths introduce clear boundaries between the different parts of the application and define how these parts can communicate with each other. Some parts may not know about the existence of other parts. A good way of building modular monoliths is to design them using system components.

Advantages

In the time of microservices, monoliths have received a bit of a bad reputation. That reputation is not entirely justified, as monoliths have several advantages compared to microservices.

Simplicity

Monoliths, when done well, are easy to develop, test, debug, and deploy. The components are contained inside a single codebase, and can often be contained inside a single project in your IDE. You need only to test and debug a single executable. You don’t have to set up a lot of supporting services to deploy the monolith: often, the executable and a database are enough.

Transactional Integrity

Since everything happens inside the same executable, you can rely on local transactions. You don’t have to worry about things like distributed transactions or sagas.

Less Overhead

Most of the system components communicate over function calls rather than network calls. This often translates to better performance of the application.

Disadvantages

Despite the advantages mentioned before, some negative feelings about monoliths are understandable. Monoliths have several disadvantages that you should consider when deciding what kind of system architecture to choose.

Scalability Challenges

It is possible to scale a monolith. You can scale both up, by adding more hardware resources, and out, by deploying more instances of the monolith. However, you’re always scaling the entire application. If only some parts of it require scaling, you may waste resources that cost money.

You may also run into another type of scalability challenge: scaling the code. As the monolith grows and more features are added to it, increasing effort is needed to prevent the quality of the code from degrading. In the worst case, the monolith can degrade into an unmaintainable "Big Ball of Mud".

Continuous Deployment Challenges

Although you can use continuous deployment with a monolith, even small changes require rebuilding and deploying the entire application. If you haven’t set up session replication and rolling updates, every redeployment means downtime for your users.

Team Collaboration Challenges

A monolith should be owned by one team, only. If you have more than one team working on the same application, you have to be sure to keep the teams aligned. The risk of conflicts in design, source control, release cadence, etc. increases.

When to Use

Regardless of the disadvantages, most business applications should be monoliths. If your application provides a single service to a limited number of users in a limited geographical area, a monolith gets the job done.

Microservices come with many buzzwords, like endless scalability and improved resiliency. They sound nice to have, but they come with a cost. You have to decide if your application is worth that cost, or whether the time and money would be better spent on something else. Often, you can achieve the qualities you need (e.g., scalability, availability, and performance) without switching to microservices. Choosing microservices only because everybody else is doing it is not a good reason.

You can do some future-proofing by making your monolith modular. A well-designed, modular monolith is easier to split into microservices in the future, should the need arise.