Software architecture - defining what is a monolith?

Monolithic architectures are often defined by what they are not — the opposite of microservices — and are frequently seen as an undesirable architecture. However, this perception ignores their value, especially for smaller systems where a monolithic design could be simpler and more efficient. This post will explore this idea by providing two specific definitions of monoliths, something that is often missing from the discussion.

Monolith as an intentional design

Some people define a monolithic architecture based on size, using metrics like lines of code or the number of endpoints. However, I prefer a different approach, defining a monolith as a single application that contains more than one business capability. I like to use the following definition from "Microservices: Yesterday, Today, and Tomorrow" by dragoni et al:

"A monolith is a software application whose modules cannot be executed independently"

But I would like to rewrite it to the following:

"a monolith is a software application which has more than one business capability"

As I interpret the modules part in the first definition as well modulated business capabilities. These are loosely coupled but cohesive units of code that each makes up a business capability. A business capability however, is a very loose term and is often different for every business area. An example of a capability could be invoicing as demonstrated at Capstera, where they define a business capability as:

a key component of business architecture, is an expression of what business does and can do. A business capability denotes the "What" a business can do, whereas a business process outlines how a particular activity gets done.

Another way to think of it is using the rule of single responsbility, if we have a service that is responsible for several business capabilities I would consider it a monolith. Sometimes it can be hard to decide whether a feature is an independent business capability or a small part of a business capability. In this situation I turn to what changes together stays together. If you have to change ten services every time you add or change business functionality, you have likely decomposed your architecture wrongly. As these services always change together they should be one application or at least less than ten individual applications. You have likely created a suite of nanoservices, which have business capabilities or even helper functions spread across multiple services.

Monoliths suffering from architectural erosion

Some look at monoliths as spaghetti code and this is often the case. It is well described by Rod Stephens in "Beginning Software Engineering":

"A software system is called ”monolithic” if it has a monolithic architecture, in which functionally distinguishable aspects (for example data input and output, data processing, error handling, and the user interface) are all interwoven, rather than containing architecturally separate components."

This definition is well written but I do not like this definition as it resembles an architecture gone wrong, rather than an intentional approach at creating an architecture. It is often the case with monoliths that their structure drifts away from the original ideas on how they should be organised. Over time monoliths can grow and become unmanageable, which creates a "resistance to change". As monoliths grow large they become difficult to replace and this can create vendor lock in. With microservices you can more easily swap out the technology or refactor a single microservice. If the business capabilities are entangled in a monolith it can be hard to refactor and this is where it starts to become the so called spaghetti or soup.

Again, I do not like to define monoliths this way as they can be well organised and have decoupled and cohesive modules. However it requires more discipline to keep the codebase clean as it is easier to accidentally entangle business capabilities with one another within a monolith. Because all business capabilities are in one place, it's easier to accidentally entangle them or make direct calls to another capability's internal logic. This can sometimes lead to quick, "hacky" implementations that compromise the architecture.

Wrapping it up

This was my post on defining the monolith architectural style, I gave you two definitions which you may recognise from the field. Please write in the comments if you disagree with the definitions or have a third one you would like to add! I hope you enjoyed this post.

Further reading

As mentioned previously, microservices are often perceived as being the opposite of monoliths. If you are interested in microservices and how they are different from monoliths I would suggest Fowler and Lewis' webpage on the topic. If you are into books I would recommend Sam Newman's book on the subject - "Building Microservices":


Disclosure: Bear in mind that some of the links in this post are affiliate links and if you go through them to make a purchase I will earn a commission. Keep in mind that I link these companies and their products because of their quality. The decision is yours, and whether or not you decide to buy something is completely up to you.