Monolithic vs Microservices
A couple of months back, I read that Amazon Prime Video lowered their monthly AWS costs by 90%, by shifting a part of their system from a microservices based architecture to monolithic architecture.
That immediately sounded strange to me despite the fact that I had no idea what either term meant. It was just that the term ‘microservices’ had a ring to it, like it was in vogue..and ‘monolithic’ well, means big and bulky and slow to change. How could this be? Today is the day I’ve decided to explore monolithic/ microservices based architecture. Let’s get started!
Monolithic Architecture -
The term ‘monolithic’ literally means ‘large, indivisible, and slow to change’ , and this is exactly true of monolithic applications. Monolithic architecture is a system design pattern where all components of the application are combined into a single unified application (single-tiered). All the different business functions of the application are present in, and deployed as a single unit.
For example — A banking application with different components like services for user authentication, statement downloads, money transfers, etc. All these different business functions will be combined in a single code base. To make changes would require developers to access the codebase and deploy the updated version, thereby updating the entire stack.
Pros -
- Simplicity — Easy development, debugging, deployment and testing as all code is located in one place
- Performance — One API can perform the same function that multiple APIs are required for in microservices based architecture
- Security — Secure data processing due to communication within a single unit
Cons -
- Scalability — Hard to maintain and handle new changes as the whole codebase needs to be deployed each time
- Resiliency — One bug can affect the whole system
- Flexibility — Hard to adopt new frameworks/languages/tech
Get Suhas Athreya’s stories in your inbox
Join Medium for free to get updates from this writer.
Microservices Architecture -
Microservices allow for large applications to be broken down into small independent parts. Think of the same banking application I mentioned above. Here, each of the business functionalities listed above is treated as a separate unit with its own database. Each of these parts communicates using via a well defined interface using lightweight APIs.
Pros -
- Scalability — Each service can be deployed and scaled independently
- Flexibility — Easy to refactor and adopt new technologies as the code isn’t concentrated in one codebase
- Resiliency — As each part is separated, bugs in one service do not impact the others
Cons -
- Complexity — with new inter service communications etc, and a higher chance of failure during these communications
- Data Management — Keeping data consistent across different services, as they all have different databases
At this point, I want to investigate the claim of ‘scalability’. Let’s look at the 3 dimensions of scalability — Users, Lines of Code, and Engineers. (From u/raddingy on Reddit)
Users — With a bunch of users, there is inherently one part of the application that users interact with the most. For example — the Facebook timeline vs Facebook account management. If both were coupled in a single web app, and the account management side was broken, there would be a significant chance that it breaks the timeline, thus breaking a feature that one person may care about, while simultaneously breaking the feature that all users care about. Next, as more users start to use that one feature, you’ll face bottle necks from the Database side, the logic implemented, and even the language that you chose to use. If it gets to that point, does it really make sense to re-write the entirety of facebook.com in C++, or just the timeline piece that is actually being impacted? Micro-services start here.
Lines of Code — With more users, and even more engineers, you need to write more code to keep up. You’ll need to implement more features, update old logic, fix bugs, remediate new security vulns, etc. But as your code count increases, so does the number of bugs. A study revealed that the industry average is about 15–50 bugs per 1000 Lines of Code. If you have a single deployable with all your logic, what happens if that bug is in a mission critical part, say the bootstrapping process of your application? Well now you can’t start your app, and either new deployments for all work is blocked (at best), or your entire service is down until you hunt down these bugs and fix them. Wouldn’t it be better to have separate systems with smaller amounts of code that are isolated from one another?
Number of engineers — As you grow, you will need to hire more engineers to keep up with demands of new features and bug fixes. Now you have 100 engineers all contributing to monolith. Not only does this increase lines of code (what I spoke about above), but it also increases the need for coordination and communication. What if Team A needs to push out a new feature today, but Team B’s work is not done? What if all teams need to work on a shared piece of code and all introduce a gnarly merge conflict. This isn’t uncommon, one place this is a huge pain is a Dependency injection container. There is also the pain of re-work at a scale that large. It’s unavoidable. There was a team that I worked for that was using Laravel as a monolith at this scale and there was no joke, three different implementations of the routing all wired up in different places. Needed to implement new routing logic? Best of luck figuring out which of the implementations need the update. Wouldn’t it be better if each team just implemented what they needed and told others how to get the behavior from them, rather than every team needing to understand the implementation of the others in order to ship code?
That’s where microservices come in. They give you the ability to tailor the individual service to the number of users using it, which may or may not be the number of users using the overall product. You can write tricky mission critical applications in C++, keep admin things that everyone thinks about after in Python or PHP, and still have a well performing application. Each microservice has less lines of code than the overall application, so in theory there should be less bugs, but also any bugs that do pop up should be much easier to hunt down because there are fewer lines of code to sift through. And when you have more than a few teams, the coordination becomes a hassle to manage in a single code base, it is much better to just let each team own their own services and deploy them as they see fit and to limit that coordination to API interactions.
Now notice, all of the problems that Microservices solve are at scale. If you are a small startup with like 10–20 engineers you probably don’t need microservices. In fact, the overhead and management of them will quickly become burdensome and you will see microservices as a problem rather than a solution.
In conclusion, both these architectural design patterns have their own pros and cons. If you need to scale independent services in isolation, then microservices would be your best bet. If you don’t need to scale and your business logic is simple, then monolithic architecture would suit your needs just fine.









