Skip to main content

Go Big or Go Home - The Beauty of the Monolith

·1989 words·10 mins
Architecture Don't Believe the Hype Simple & Smooth

How come I am mad? #

Microservices are propagated as the de-facto standard for creating new, scalable applications. I have no problem with stating that out loud, because this is how I perceive the current state of the industry. How do I come to this conclusion? I like to take a quick peek at what up-to-date literature has to offer and while there is a broad offering for how to do microservices the right way, the only eligible result for Monoliths is limited to the topic of how to rewrite your monolith into microservices the right way. Still not convinced? Take statements like this one, right there in print, prominently places as the very first sentence in a book: “Every service you build should be a microservice”. I wholeheartedly disagree and will point out why I am actually convinced of the opposite and want to propagate the notion of “Every application you build should be a monolith, unless there is valid reasons to split it up!”. Let’s dive right in!

very majestic monolith being pure mono lit with shakespeare

Disclaimer: I am not going over what microservice and monolithic architectures are, because I assume you having landed on my here site are familiar with these concepts. If not, I recommend to do some minor digging before getting started.

The root of all evil #

First things first: how did we get here? Netflix pulled off a huge stunt and casually on the side snitched us all mightily. They went ahead and did nothing else than showing off, shouting out loud that they had switched to microservices, caught lightning in a bottle and can see nothing but much greener grass than before. And everyone was left in awe, blindly accepting microservices as the real deal and the new sheriff in the town called ‘Software Architecture’. So, bunches of easily influenced consultants, fankids and highly-paid executives set out to follow their lead. The only problem was, most of the software that we as developers are tasked to implement is not a streaming service with a green-field domain.

Shiny happy promises #

Winning all of the industry over was not a hard sell though, as the collection of benefits that were and still are advertised with the switch to them tiny winy services was no less than purely legit (only problem, as we will see further down the line, all to take with a grain of salt). And if they actually were only nearly as advertised, who wouldn’t be in for it? They include, but are not limited to the following:

Independent deployments #

Legend says that microservices let you deploying without affecting other services being independent deployables, but that is not as easy as it sounds. The obvious but not only problem is compatibility of APIs that are used to communicate across services. Those are note only technological overhead in terms of having to be implemented, but mostly result in unprecedented operational overhead with aligning APIs across team borders and having to keep APIs compatible at all times. With a lot of workflows going through multiple services after being triggered by a single user action, deployments will actually have to be coordinated a lot of the time. explaining order of service deployment in microservice architecture meme

Fault isolation #

Does a spread out architecture save your application from going down? Well yes, but actually no. A lot of the problems (if not most) that occur within our software are not necessarily of the server-not-starting up or service-being-completely-down kind, but rather certain edge cases that occur under specific circumstances (a certain range of users, etc.) isolating the problem to a certain degree from the get-go. Having said that, how isolated a service that is completely down or malfunctioning actually is depends highly on where within the call-chain that service is. If the result is necessary for other services to function within the workflow your fault is as isolated as a penguin in Times Square We’re talking situations like “Yeah sure, payment-service is currently down, but on a happier note, the rest of the application is still up! So, our uptime KPIs might be good!” So, this one is a hard ‘maybe’ from my side.

Parallelized development aka faster time-to-market #

Multiple completely independent teams that do not have to wait for each other to finish or phrased differently every project managers wet dream.

And what cannot be left out, because it leaves executives all across the globe drooling themselves and going full-blown Fry-Meme, faster time-to-market (going off on the whole time-to-market obsession is probably worth its own rant in the future, so we will leave it at that for now). The idea is

Flexibility in the choice of technologies #

This is one of the few points that got me saying, I got to hand it to them. This is one of the truer actual benefits that also translate just as stated to the real life. The only question here is really, whether you actually and for realz need (and I mean NEED) that kind of technology split. Because, doing that just for fun, because Rust people want to write their services in Rust and Java people stick to what they’ve known for the last 20+ years is definitely NOT worth it. Taking care of all the additional problems that come with microservices laid out later is no fun in no language.

Improved scalability #

Now, get your notebooks ready, because this one is of major importance. Being able to scale different parts of an application independent of each other, as splitting up your services to run on different machines enables you to

they lied to me about microservices meme

Let’s go on and face the harsh reality. After all, nobody likes being lied to.

The (ugly) truth #

A neat little side effect of distributing your application across multiple services is that suddenly, everything that used to be easy peasy lemon squeezy, all of a sudden becomes difficult, difficult, lemon difficult. No worries though, big bro Netflix got your back with a respective library helping you to deal with all those newly-introduce issues. This at least brings you one step closer to your initial goal - getting your own stack on par with Netflix’. Yay!

amplified problems microservices

… and all the problems you had initially and were hoping (btw. the very worst word in the English dictionary) to get rid by switching to a new and funky architecture style are back to bite you and they have evolved from Magikarp to Gyarados in terms of ferocity. But that’s not all! They come together with a new set of problems that are on the house when dealing with distributed systems. Be it…

  • service discovery
  • observability/tracing
  • debugging
  • security
  • resiliency/retry handing
  • idempotency
  • transactions

… pick your poison.

Should we really? #

Distributed systems used to be feared. You would be met with pitying and appalled looks when telling others about your terrible fate of having to incorporate remote calls into your services (who ever actually used them Remote EJBs??). What about the transactions, retrying, performance and security? YESS, those are the right questions!

As stated previously, microservices are best seen as a possible solution to a very specific problem. That problem is performance bottlenecks limited to certain parts of an application that have to be tackled by means of horizontal and/or vertical scaling and possible using a lower-level language to squeeze out every last drop of performance gains possible. Prerequisite for this of course is familiarity with the non-functional requirements of the application and let’s be real that is something we are lacking most of the time (especially at the beginning of projects).

So no, distributing your application across multiple services is not something you ‘just do’, but is a decision that should be made based on a concrete demand and not for the heck of it.

Pulling it off is major tricky #

Besides all them 99 problems mentioned above, what makes doing microservices the right way even more tricky is the impossible task of understanding the domain you are working with. Many businesses are no 21st century startups but used to be brick-and-mortar and those come with major baggage within their data, processes, culture, everything. Trying to split that chaos into neat little slices is just plain bold. Don’t forget what Mr. Conway said: “Crazy company = crazy processes = crazy code”.

In addition to the impossible domain knowledge, you need mad developing and architectural skillz and experience. Problem is, it has never been easier to become a developer and the whole industry is so full of itself having completely lost the sense of what is important that is has become almost impossible to gather the right kind of developers. If the industry was as inclusive in terms of other factors such as sex, gender, minorities, etc. as it is regarding skill, I would be sooo happy.

If I was in a situation where I really, really have to, the gameplan I would draw up to at least not completely screw it up looks something like this:

  • All services developed by same team or a handful of teams with outstanding communication with each other (crossing organizational borders with this is a surefire recipe for disaster)
  • Be sure to have very profound knowledge of the domain at hand (and no, good understanding does not equal profound knowledge)
  • Have a clear-cut understanding of the non-functional requirements that you want to counter with splitted up services
  • Assign developers that really know what they are doing

What I prescribe as your coding therapist, however, is: “Just don’t do it… unless you really, really, really have to and know why you are doing it”. Be aware that microservices are not a standard for your software architecture, but serve as possible solution to a very specific problem and on the flip side comes with its very own set of problems. As everything in the (developer) life, with everything good, the respective tradeoffs are right in your face. It’s like prematurely taking your medicine, the side effects are still there without any positive effect.

The Beauty of the Monolith #

Why did I spend the last 1000+ words bashing microservices? Am I a notorious hater of progress and everything new? Is it pure and naive glorification of days past? No, not at all. All I want is to get the word out that Monolithic architectures are NOT legacy. Speak after me: “Monolithic architectures are NOT legacy”. We are not in a in this corner we got the contemporary standard and in the other corner we got the thing of the past kind of situation. Monoliths still are a valid software architecture choice solely based on all the problems that you can avoid by sticking to it.

hello fellow kids monolith getting new needed attention

What we (as developers) really want #

From my personal experience, most of us developers have an above-average desire for order. Clean separation of concerns, this is what we want (what we really, really want). The problem, software tends to be messy, because its purpose is to serve as abstraction for the real world, which is… a shitshow to be frank. Microservices in theory are a really nice concept to help us keep all these abstractions organized. Problem is that reality usually hits very different and real life does not give a rats ass about our cute little abstractions. In fact, I am a firm believer in the fact that there is no such thing as a clean solution in form of the “correct” abstraction to every real life domain/problem out there. Reality is just too complex. what do you want - what do you really really want?

To sum it all up, microservices should absolutely not to be taken as the golden standard of modern software architecture. That idea is just plain wrong. Rather, splitting up an application into different independent deployables is a solution to a very specific problem, which mainly lies in different parts of an application having very different non-functional requirements and scaling needs. This is when a split actually makes sense. It does not help at all to get your application in order

– Rant over