Press "Enter" to skip to content

Monolith: The Good, The Bad and The Ugly

After initial very warm welcome and a wave of hype microservices are no longer considered a silver bullet for all software pitfalls. We, as a community of engineers, started to notice the significant complexity they introduced. The plain old monolith approach started to get mainstream attention once again. That is why, today I would like to bring it and its different subtypes to your attention in more detail.

Why It Matters?

Well, there are a couple of possible traps which you may fall prey to while working with the monolith. These traps and their possible consequences, are strongly related to the monolith subtypes I will cover below. These subtypes have their respective names, but I prefer to name them: the good, the bad, and the ugly according to the number of headaches they may cause for its maintainers and owners.

In a more reasonable way, they go like the following:

  • The good – the modular monolith
  • The bad – the distributed monolith
  • The ugly – the traditional monolith

The Ugly

The plain old monolith or the ugly. It has its own problems and quirks – it is hard to maintain, deploy, and has some performance bottlenecks, but at the end of the day, it is doing its job. That’s why I call it ugly. Not the prettiest, but the job is done.

It is the most common case in monolith implementations as it is a kind of natural way of software progress. When there is not too much to think about long-term problems and consequences, and “now” is more important than “later”.

Some traits of this subtype:

  • Single codebase and deployment unit.
  • In-system communications, no outgoing requests.
  • Tightly coupled but simpler to understand, up to a certain point.

The Bad

The distributed monolith or the bad. It is probably the most common anti-pattern when dealing with migration of a monolith to microservices. In particular, it is a result of failed transitions to microservices.

Essentially, it is a monolith but split across multiple services. There may be more pitfalls hidden behind this, but this one is the most important. While in some cases a distributed monolith may still do its designed job, it is more likely that it will fail.

Some traits of this subtype:

  • Split into multiple services.
  • Communication over the network, usually a synchronous one.
  • Still tightly coupled, like a monolith, with badly designed responsibilities inside each service.

The Good

Modular monolith or the good. It is a monolith with clearly designed boundaries between the modules inside—thus a name, modular monolith. Different modules can basically be developed independently, using only in-place interfaces to call one another.

It is the best subtype of monolith that exists; usually, it is also ready to be split into microservices when the need arises. It turns some of a monolith’s disadvantages into advantages, yet keeps the whole application as a single deployable unit.

Such an approach greatly reduces the cognitive and economic burden needed to manage and run microservices. This architecture is easier to develop, test, and deploy while providing a clear path for gradual evolution into microservices if needed.

Some traits of this subtype:

  • Single codebase and deployment unit.
  • High cohesion inside the modules and loose coupling between the modules, at least as possible inside a de facto single service.
  • In-system communications, no outgoing requests.

Monolith Migrations Tips&Tricks

If you ever decide to migrate from monolith to microservice here is a few good tips, for you to avoid ending as bad.

  • Analyze First and Foremost only after carefully analyzing different flows and dependencies you will be able to make correct decision later
  • Migrate By Domain Not Layer it will make whole process less mind-blowing while also reduce the chances of creating high coupling between components
  • Do It Step By Step do not try to migrate everything at once, do it domain by domain, or by any other approach that comes to your mind, maybe migration to “The Good” is a good idea for a start
  • Contract Test Right Away thought about contract test, and all necessary setup from the start
  • Talk, Talk and Talk even more be even over-communicative with what you are doing, be 100% sure that all the involved teams know what you are doing and how it affects their work
  • Build Clear Ownership each service/module need to have clearly assignee owner, there should not be situation that multiple team are responsible for a single service
  • Know When To Stop chances are that you are Netflix and probably do not need an architecture of 100+ microservice, think carefully what need to have a separate microservice and what may be merged with some other service

Summary

Putting the whole text into a more readable and understandable format:

Monolith SubtypeDeploymentCommunicationCouplingComplexity
Traditional (ugly)Single deployment unit.In-process communicationTight coupling between different componentsGrows with the growth of the code base
Distributed (bad)Multiple services – changes in one often require redeploying others.Synchronous communication over the networkTight coupling between servicesHigh complexity due to distributed nature of deployment
Modular (good)Single deployment unit, but internally organized into well-defined modules.In-process communicationLoosely coupled modules with clear boundariesModerately complex due to strong modularity and clear responsibilities

Now you know more about different approaches to building and working with monoliths. Thank you for your time.

Be First to Comment

    Leave a Reply

    Your email address will not be published. Required fields are marked *

    Table of Contents