Monolith vs. Microservices Architecture

November 28, 2019

Microservices

Monolith vs. Microservices Architecture

Continuing our journey of learning more about Microservices, today, we’re discussing the differences between Monolith and Microservices architecture patterns. As we’ve already investigated what microservices are, let’s start with the concept of the monolith. 

Building a Monolithic App

A monolith architecture pattern implies that you build an app as a single-tiered and self-contained software unit without modularity. Here all elements of the app’s code represent a single layer from a single platform, independent from other applications. 

The design philosophy behind the monolith approach is to make the stand-alone software responsible for a full cycle of designated functions, not just for one particular task. Take, for example, personal finance management apps and word processors – most of them had been using only the monolith basis until recently. 

Following Monolith Pattern

Let’s say, your project is to build a shipment web app. At first glance, this software has to have such features as user registration and management, order forms, logistics options, route maps, price and delivery time calculators, invoice generators, various payment options, and an admin panel. Once a shipment company receives an order, the app has to present the admin with the list of matching delivery options, contacts of responsible workers, and so on. 

The monolith formula is to model the app first. A team of business analysts, PMs, engineers, and architects create a project roadmap of how things are going to work at the scale. Where each form goes, what will be the user stories, business logic, how many shipment categories they will have, etc. A database will be responsible for storing all the app’s information; there also has to be an easy-to-navigate, intuitive user interface. So, we have a frontend side that communicates with a backend side. 

This backend is deployed exactly as a monolith with its own attached database. The app can also communicate with third-party APIs, and it supports a full range of devices (desktop, mobile, tablets). Sounds familiar? It’s because we’re very accustomed to this architecture. It’s been working efficiently for us for a long time. 

Advantages of Monolith Architecture:

  • Simple Development. Your overall tech stack on the project will be only a few languages, frameworks, and databases; a single IDE is usually enough for your monolithic code. 
  • Simple Testing. Having a monolith, you mostly test a single piece of software, with the occasional need to mock several external services for integration testing. 
  • Simple Deployment. You just need to deploy the final artifact of your monolith (WAR file or directory hierarchy) on the suitable runtime and configure the designated properties. 
  • Simple Scaling. You can scale and improve the app’s availability by running multiple copies of the software behind a load balancer. 

Disadvantages of Monolith Architecture

Then why even bother about microservices? As with anything, there are two sides to the coin. Along with benefits, the monolith has several drawbacks. For instance, you might want to empower your shipment app with additional features. The app’s codebase has to grow by who knows how many lines. The team grows in size since you probably add more needed engineers. Here come the problems. 

The bigger your app becomes, the harder for each new developer to show productivity right from the first days. It’s because the app’s codebase gets challenging to sort through or modify. Not to mention that you might need to set up several teams to maintain the particular functionalities of your massive monolith – for design, for frontend, for backend, for QA, for deployment. These teams can’t work independently; they must coordinate their actions and efforts to meet each other at the redeployment stop. 

So, at this stage, the drawbacks of the monolithic approach become more visible and significant: 

  • The code has an enormous number of lines that not every developer can navigate through. 
  • New developers’ productivity is low. 
  • Monoliths have limited reusability. 
  • The app is difficult to modify and update, which slows down the development phase. 
  • The IDE overloads and becomes slower, and less productive. 
  • The technical debt increases over time, but the tech stack must remain the same as at the start of development. 
  • Due to the lack of modularity, the code’s quality declines with each change being made. 
  • Continuous deployment of an entire app becomes harder and harder as the code grows. 
  • The operational agility collapses because of the frequent redeployment rounds. 
  • Scaling gets more complicated, and one-dimensional due to the increasing volume of data – caching is less effective, memory consumption increases, and the app gets slower. 

Just imagine, you need to change the database for one small part of your app. What to expect? A lot of redevelopments for several app’s sections, not just for that little feature. This comes along with huge risks of scaling the entire piece of software, slower deployment, and the inability to predict if the redevelopment will even work. 

Building a Microservices-based App

So, what about the microservices pattern? Business-oriented APIs represent their capabilities. Simply put, each microservice carries out a core business capability, a valuable asset to the business. These assets are highly scalable to be used in multiple contexts, without direct binding through must-have languages or shared libraries. Each service is reusable for more than one business process and over different business channels. 

As the microservices are loosely coupled, the dependencies between them and their end-users are minimal – the consumers won’t feel any changes in the implementation of the particular service. Combining robust API management and up-to-date cloud deployment and integration technologies, the microservice architecture pattern divides the monolith into a set of fully independent software units. This principle of modularity allows updating, modifying, and replacing the whole system or service components, without any impact on end-users. 

Microservices Advantages

Microservices bring the following benefits to your application: 

  • The principle of modularity increases the overall agility of the development process. 
  • High modularity, scalability, and reusability of the app’s logic parts. 
  • The development tech stack is unlimited. 
  • Easy code maintenance – fixing, modifying, and replacing the parts of your app doesn’t require wholesale redevelopment. 
  • Scalable and independent engineering teams – services are small, so you need only a handful of developers. 
  • New developers’ productivity is higher due to the smaller codebase. 
  • Services are independently developed and deployed artifacts, which significantly speeds up the time to market. 

How to Migrate from Monolith Architecture to Microservices

So how to implement monolith to microservices migration and build your shipment app using the microservices? Converting monolith to microservices starts with the design phase, where you need to define the structure that will present the app’s functionality as a set of loosely coupled services. This means identifying the subdomains of your main domain, which correspond with particular services that represent different parts of your business. 

Exploring the main domain of the shipment services, we can roughly subdivide it into 3 subdomains:

  • The user subdomain will deal with user authentication and management. 
  • The order processing subdomain will be responsible for the full cycle of order processing – price calculation, invoices, discounts, and delivery options. 
  • The admin subdomain is related to the supplier’s side and the management of workers responsible for delivery. 

Now you have clear connections between these subdomains and understand the difference between monolith and microservices. Remember, your microservices should be independent of each other. So, you need to follow the domain-driven design techniques and patterns to design an appropriate model. First, you should duplicate the features that depend on each other in all subdomains to make them separate entities. Then, each subdomain will process its data on its terms, so there have to be separate databases for each of the three. Avoid sharing databases – it’s bad manners in the world of microservices. 

When these things are cleared up, you’ll end up with a map of services for each domain that can be put into design and production. Having small parts of the software to develop, test, and deploy, your team will work faster and more productively, avoiding overloaded IDE, limited tech stack, and overall chaos related to redeployment. 

Summarizing Microservices vs. Monolith Architecture

Of course, both monolith and microservices architectural patterns have their advantages and drawbacks. Microservices are not a panacea for any project, but it’s a good choice for large, complex software. Small teams, higher agility, easier management, faster development cycle… Is it the best fit for your project? The choice is yours. In the following articles, we’re going to explain all the elements in the microservices ecosystem to help you determine when using this architecture is smart. 

P.S. If you’d like to get a free professional consultation on how to migrate from monolith to microservices, reach out to us at any time. We’re ready to help you decide whether the microservices are right for your project. 

 

Let's Get Started

If you’re ready to succeed, we are ready to help!

Discuss your project