Are Microservices Better Than Monoliths?

The year is 2022, and Kubernetes is wreaking havoc on software delivery as we know it. Applications are going through modernization programs so they can be converted into microservices, but they are coming out the other end as distributed monoliths. Next thing you know, services exist across several clouds and even in your data centers. And, of course, the large majority of enterprises aren’t just greenfield.

Many have a combination of technologies stacked over decades, including mainframes. Want some perspective? Check out this article on how COBOL still powers the Global Economy. In this blog, let’s examine the polarization of Kubernetes and microservices. Is it a zero-sum game, or is the real world destined to merge many different types of solutions in organized chaos forever? Before jumping into the world of the microservice, let’s visit our old friend, the monolith.

Monolith
  1. : a single great stone often in the form of an obelisk or column

  2. : a massive structure

  3. : an organized whole that acts as a single unified powerful or influential force

    Merriam-Webster

A monolithic application consists of a server-side application, database, and client-side interface, all of which are deployed as a single unit. You could even have a monolith in the cloud constructed with a cloud-native database, load balancer, and application running on virtual machines. The vital question to ask is, will rebuilding the application with a different architecture replace more problems than it is creating?

Monolithic App
Monolith

Of course, the answer to this is, it depends. Greenfield applications that need to scale horizontally can do so in full monolithic glory using a combination of infrastructure-as-code, image management tooling, and cloud-native services. Yes, fully automated, immutable, pipelines-on-pipelines, and reliability grandma would be proud of.

And the best part about this is simplicity. In my experience, having something simple enough to match where an organization is at ends up being far more valuable than something too complicated to troubleshoot, understand, or upgrade. Technology affords us the means to simplify things, and in return, our brains tend to overthink and complicate it.

A monolithic system’s initial simplicity can be appealing in many cases. Defining requirements, testing, and getting your MVP off the ground is quick. Some of the premiere companies built on microservices, like Netflix, started with a monolithic architecture. Check out this talk given by Ruslan Meshenberg on their journey:

Some of the everyday shade thrown towards monolithic architecture include:

  • Diminished understanding over time of the application’s architecture as a whole
  • Lack of modularity, thus limiting reuse or replacement of individual components
  • Ability to make quick and reliable changes following increased growth + complexity
  • Slower innovation coupled with a vastly competitive market; Risk of losing market share
  • Scaling limitations; Entire application can scale, but not specific services
Zooming Out
Just because an application is monolithic doesn’t mean it’s legacy or even outdated. If you have a single monolith with clearly defined module boundaries, sound design, and the ability to scale to an organization’s needs, then why change anything at all?

Microservices position themselves as the paladin, leading the cause against the feared and long-lived tyrant, the infamous Monolith. The microservice architecture breaks up a given application into loosely coupled and independently deployable services. Each of these services has its own codebase, database, and management model. Kubernetes has emerged as the vehicle of choice for service orchestration. A common goal is to align those services to business capabilities with clearly defined context boundaries.

Microservice App
Microservice

Context Boundaries
In large enterprises, context boundaries are generally predicated on the domain-driven structures of the organization. Furthermore, these contexts forge the boundary for the size and scope of the service. Domain experts must collaborate with development and infrastructure teams to ensure success and cohesion across parallel domains, making this concept a big hurdle for many modernization efforts.

If a system can’t support exponential growth, thus failing to deliver on business goals, then microservices could be the answer (meaning they solve problems related to horizontal scale). In large organizations, new technologies can often be championed to solve human or organizational problems. This tends to snowball over time as the number of solutions and technical staff to operate them increases. Solving causal problems requires an accurate understanding of their causal structure. One of the best explanations on this I have heard came from Rob Brigham at re:Invent 2015:

In this talk, Rob recalls Amazon’s retail website back in 2001 and how it was a large architectural monolith. He then explains how this monolith became problematic and why breaking it into smaller pieces was the right solution. In Rob’s story, maintaining, testing, and deploying in smaller chunks solved the scaling challenges Amazon was facing.

Microservices Make Systems
It should also be noted that although you can deploy microservices independently, this does not mean they are entirely decoupled. The goal is to produce a distributed system from a collection of services working harmoniously together for the good of the system as a whole. And although using microservice architecture helps manage and scale complex systems, it can also introduce many new and often unquantifiable complexities as a result.

On GoTime#114, Kelsey Hightower talked at around 54:20 about one of his unpopular opinions which is, “Monoliths are the future”. You can read some of the excerpts here, but I would suggest going back and listening to the entire show to get the full context. Some of the common criticisms of microservice architecture include:

  • Transitioning from monoliths require comprehensive understanding and refactoring
  • Distributed nature adds complexity to testing; Increased overhead as services grow
  • Time and cost associated with refactoring existing app portfolio to microservices
  • Visibility and traceability challenges; New tooling required to manage sprawl
  • Increased moving parts create a larger attack surface; New points of ingress/egress
  • Relationship between services is often as efficient as collaboration between teams
Is Something Broke?
Enterprise Ops teams typically absorb a lot of data that drives metrics for the business. The real test comes when something is broken. How quickly can an operations team restore service? If it is not in their power to restore service, how fast can the fault be identified and escalated to the appropriate team that can take action? Debugging microservices often comes down to sifting through never-ending logs. Since many issues stem from failed integration between components, using methods like distributed tracing is necessary to understand the relationship between logs to identify issues between services.

You get to work and sit down at your desk (or maybe roll out of bed and turn on your laptop). You attend your company’s Townhall presented by the CTO. This is the year of Digital Transformation. If Google can microservice on the kubernetes, so can we. It is time to modernize these legacy apps. What would I say if I had a few minutes to talk to this CTO?

Many enterprises today are still organized hierarchically, making the whole structure complex. This directly impacts the speed at which critical decisions are made, thus delaying work from being completed. In post-pandemic life, the ability to make quick and effective decisions is crucial at any rate, but especially when approaching modernized ways of delivering software. Finding ways to flatten the structure, clearly define the roles, and push empowerment for decision making lower can help with organizing for the future.

In life, sometimes the human side of us tends to hammer a square peg into a round hole. Designed initially not to fit, we continue to take swings. If the hammer is big enough and the peg is as frail as many applications, you will get the peg into the hole. Now the operation of the object housing the peg may work, but not to its full potential.

When it comes to transitioning monolithic applications into microservices, the result is often distributing the monolith. This type of application is deployed like a microservice but built like a traditional monolith. I have often seen this happen with applications hammered into the managed cloud provider kubernetes services. Are you in this boat? Start with these questions:

  • Are any of our microservices sharing a datastore?
  • Is our rock-star developer working across multiple microservices?
  • Does making a change in one microservice require changes to others?

In this scenario, we retain some of the problems we were initially trying to escape. Changing a small chunk of the application still comes with redeploying the whole thing, the horizontal scale is not as efficient as it could be, and deployments are slow. Also, the compound interest begins to sting because we have the complexity of microservices.

Many variables outside the application may impact the overall picture, including culture, infrastructure, adequate staffing, and technical talent. While no single solution can solve all problems, it stands to reason that a thorough understanding of where the culture and technology are should be the first step prior to planning any major transformational exercises. Attempting to modernize misunderstood and misrepresented applications with Kubernetes is not a strategy.

In my opinion, many legacy applications will continue to run in the enterprise space. Some will end up getting rehosted in the cloud, replatformed or decommissioned in favor of equivalent SaaS offerings. Others will go through large modernization initiatives coming out the other end as distributed monoliths running on kubernetes. Purely greenfield applications have a better chance at seeing real microservice architecture and reaping the benefits. Are any of these things wrong? I don’t think so.

The only constant is change. The ability to acknowledge that something isn’t working and promote the fail-fast mentality from the top will encourage new ideas, technologies, and practices that help keep an organization relevant. If there is a culture of fear, then innovative solutions from talented engineers will get sidelined. The monolith VS microservice conversation doesn’t matter. Delivering the best possible product to the customer with the resources available to you while delivering on business goals does.

Big thanks to Kiran Dongara for taking the time to peer-review. Your wisdom and feedback are much appreciated!