Contrary to a popular belief, microservices are not a panacea. If something is good for everything, it’s good for nothing. Many managers compare microservices vs monolithic architecture and want to know which is best for the current company’s project. Microservices are a fantastic way to make the digital product agile, and scalable. Monolith is good when you just want something to be done.
Table of contents
- Microservices architecture vs microservices – an overview
- #Monolithic architecture vs microservices architecture – what is good for what?
- Microservices vs monolithic architecture – pros and cons of each
- Give it a go!
Microservices architecture vs microservices – an overview
Sure, this is an oversimplification because the usage of monolithic architecture is vast. Still, a healthy percentage of applications in the world run on the monolith. As you will soon find out, there are still fantastic arguments over this type of software. Not everything that has a “microservices” phrase in it is golden. Or, should we say, you don’t need them in every single case. To answer the question of what is good and when we first must go up and take a bird’s eye look.
First and foremost – digital products are not the same. To choose the right application architecture for your app, you must focus on what’s best for users and your company alone. The software has to be quick and responsive and easy to use. Plus easily built, maintained, and enhanced in the future.
Generally speaking, there are three tiers for each app:
- User interface (UI). This provides a graphical interface to create a user experience that is crucial in every application. With fierce market competition and zillions of similar products out there, you need to create a positive first impression.
- Business logic. This layer contains the code for the entire application and provides functionalities to the user.
- Data layer. This tier stores information that the application needs to run, as well as data on the current application’s state.
Sounds simple enough but if you translate all of it to actual code it suddenly changes. Rapidly and significantly.
A monolithic application’s structure is often referred to as a spaghetti code. This means that it has a large complexity and puts additional pressure on developers. Unless you do it right; with a modular nature, good API, communication between modules and no hard dependencies on the database’s side.
The result? The development velocity is poor at best and granular scaling (independent development of part of the application) is out of the question. Polyglot programming (using multiple programming languages to make up for shortcomings of a chosen one and provide additional functionalities) is very challenging. Additionally, if something breaks, chances are the entire app goes down.
Microservice application’s structure is based on an idea that developers can and do work only on what they need at the moment and the application as a whole has multiple specialized parts that are highly independent, yet cooperating. Each functionality can be written in a different language and has dedicated solutions, specified for the function alone. If something breaks, it’s the single microservice that suffers and goes out of order. The rest of the app can be available to the user.
This is how it works:
In monolithic architecture, everything works somewhat like communism. Orders are given from the top and not evenly distributed among party members that communicate them down the road. It’s totalitarianism. There is a general principle (a spine) and few vertebrae directly beneath.
In a microservice architecture, we have a democracy and free market. There is a general principle that connects all but other than that, everyone’s independent. Services are independently developed and maintained. They also communicate with each other on a need-to-know basis but it’s an organism rather than a hivemind.
In the simplest configuration of a microservice architecture, the communication between various services is point-to-point. They communicate directly with each other. You can extend this communication pattern by using load balancing. You will need to do this individually for every single microservice you want to scale. Through something called a “load balancer” (or Amazon EventBridge) you can pattern-match on the properties of inbound messages to assign them to a proper type of microservice.
This gives you immense power. You can extend the functionality of the entire system by introducing a new microservice and simply updating the load balancer rules. It’s like putting one wheel to a newly developed car and having all four of them instead of just one. Sure, it doesn’t work exactly like that but you get the point. If something can be done quicker, easier, and more efficiently, why not?
Monolithic architecture vs microservices architecture – what is good for what?
In a nutshell – if you have a strict budget and need to develop an application that will stay the same over the course of its lifetime, pick a monolith. If there are developers that are fluent with only one language and technologies that surround it, pick a monolith. Under these conditions, developing a single and integrated system is your best option.
A monolithic application means lower startup costs, lower development complexity in the first stages of the life cycle (one programming language, one repository for everything).
However, microservices are phenomenal for quick development and time-to-market. They are perfect for making optimized and in-budget pivots in response to market demands. With them, you can scale applications at will and not think about costly makeovers for the entire product. They also offer lower operating costs at scale and high reliability. In the long run, dough. First you need infrastructure and investment in DevOps’ work to make it happen.
Design considerations for each architecture
To make the right decision, ask yourself these questions:
- Who are the end-users of your application?
- What is the most important to them and how can your product deliver necessary solutions?
- What are the services your product will offer?
- What are the inputs and outputs for your application and the format they will be in?
- What firepower do you have? If you got software developers on board, can they produce an outcome quickly enough and with the necessary quality?
- Can you afford outsourcing software development and participate (as the client) in weekly meetings to oversee the process?
- What is the deadline for the app? Is there a high urgency to reach the market and can it stay on the shelf for months to come?
Over time, monoliths can evolve into big and muddy structures with little to no transparency in the code and their comments. It means that it’s very unlikely that a single developer, no matter how good, efficient, and experienced, can understand, maintain and change applications on his own. The longer a monolith is used, the bigger effort it needs to keep it alive and running. It generates another problem – potential reuse is limited.
Scaling a monolith is difficult because each introduced change requires a corresponding change in other parts of the same system. And since everything is linked to everything (in a badly built monolith)… It’s like a domino. If I want to change functionality X, I need to go through everything else and make sure my change doesn’t affect other features and levels of the same system. Uncomfortable at best.
Usage of a single development stack also makes it difficult for the future. Monoliths are known for their “single tool” approach. If you want to make a product as a monolith, you early pick a stack and stick to it through the entire development process. Changing something down the road is difficult and costly. Introducing new languages, frameworks, libraries and accompanying technologies is difficult.
Unlike monoliths, microservices-based applications run through business-oriented APIs. It means they contain business capabilities as well as the implementation of the services (alongside integrations with 3rd party APIs). The business logic is hidden from the user and the interface, which pursue different goals.
Microservices, as the name itself highly implies, are small. They can be developed and managed by small teams of developers which not only keeps the codebase clear but makes the service itself manageable. And not only for the team who originally worked on it. A good practice is to keep everybody in the loop (through rarely occurring in-code comments, tests or architecture diagrams for example) so if another team needs to pick up the slack, they can just know everything that is to know.
Microservices can be reused by other services and applications. Without direct coupling through shared libraries. That speeds up the development process and makes it easier to use the same portions of the code to achieve different results.
They are, however, dependent on each other by design. Every microservice out there performs work that is assigned to it and required by the overall system. In this point-to-point synchronous architecture, the dependency tree might be difficult to manage. As the applications grow and the company (and the market) requires additional features, the number of involved microservices and mutual connections between them can be a real challenge. That’s why it’s important to factor in the role of team augmentation services that can go with you through the entire process and take the edge off.
The team responsible for building an application in microservice architecture should be experienced and know the topic through and through. For example – service coupling can be a real issue in the development process. It’s a situation where one or more microservice become codependent and new versions of two or more services must be deployed at the same time. You can easily achieve that with object-serialization libraries. They will keep all services fully matched. You can monitor their properties in JSON or XML messages.
Second issue – reuse candidates. Engineers must spot them easily to prepare the system (and development process itself, for that matter) for code recycling. All of it – documentation, test consoles, logs, and QA reports have to be prepared ahead of time. It’s easier to use something from the past than building it from the ground up.
Close monitoring of potential and real interdependencies is also very important. Updates, upgrades, downtime, outages, and others can impact the app’s performance and public perception.
Microservices vs monolithic architecture – pros and cons of each
Each approach has advantages and disadvantages that can be considered useful in your product. What are they and how can you use them? Let’s dive deeper into the “conflict” of microservices vs monolithic architecture.
Advantages of monolithic applications:
- relatively simple to develop
- relatively simple to deploy
- problems of network latency and security are still important but significantly less in comparison. Unless you have a weak spot in API – this can derail the entire system or give access to another application. The “attack vector” is significantly bigger
- easy testing and error tracing
- defined boundaries make it easier to control for developers, especially juniors and mid-levels
- no need for a special intermediary service for communication. Components talk to each other within one environment
Disadvantages of monolithic applications:
- too difficult to manage over time since they become too large
- the necessity to develop a whole application to implement even a small change
- increased start-up and deployment time with the corresponding size of the application
- it’s very difficult to adopt any new technology to the product
- reliability problems – a single bug in any given module can collapse the entire product
Advantages of microservices:
- easy to manage
- easy to introduce new technologies to the product
- business as usual – an application can run even if some of its microservices malfunction (the so-called fault isolation)
- horizontal scaling – if one microservice experiences a significant load, it’s the only one that needs a boost
- each microservice can use different technology based on business, not technical requirements
- the team don’t have to focus on solving complex technical issues; they can instead keep tabs on realizing business logic and the client’s goals
Disadvantages of microservices:
- high requirements for knowledge, experience, and technical proficiency for the development team
- system complexity rises with each added microservice
- independent deployment of each microservice is complicated
- usage is costly and prone to latency issues
- debugging is difficult and requires in-depth knowledge from the quality assurance team
There is also one significant issue to cover in the end. Measurement or monitoring, if you will. Monitoring used for monolithic architecture is called telemetry. It’s focused on metrics per server. Metrics are time series with implemented “checkpoints”. Through them, you can measure CPU usage, memory loads, disk space, etc. You can also measure response times on webspace endpoints and generate logs.
It’s a little different for microservices. In this case, you need to solve few challenges:
- how to monitor the health of the system without observing each individual component
- predict possible problems and areas that can arise in
- diagnose issues and mitigate faults in a manageable fashion
Every point is important, but the last one is crucial. If a monolithic application is down, it’s down. Until the development team gets it back up, there’s nothing to do. If something goes wrong in a microservice-based application, users can usually spot it. A part of the product is faulty and it shows. From the customer experience point of view, it’s better to have a maintenance time to rescue the app than a screen when some functionalities are accessible but none that are currently important. It brings frustration.
It’s another argument for going with a team that knows what it’s doing.
Give it a go!
Monolithic vs microservices architecture – there are multiple layers of these issues and none can be solved by simple “yes” or “no”. Microservices are not a universal tool for everything but they are, however, widely popular among developers. They are also the future since a large portion of the economy scales into the direction that needs benefits provided by this particular technology.
What can you expect in the future? Even more individualized and hyper-personalized approach to the nature of your business. A software development company has to provide a unique experience and focus not on technology but on providing the best possible business outcome. Technology is always a tool.
Having said that… There are multiple fields to choose from and focus on in the development process. From web development to mobile development and UX and UI design. All of them require seasoned engineers. And what can be associated more with seasoning than pepper?
See also our two other articles: Microservices Patterns and Practices and Companies Using Microservices.