The battle of architectures: Monoliths vs. microservices

Compare these two different architectural styles and learn how to make an informed decision on when to use monoliths versus microservices.

Meric Aydonat Meric Aydonat

You may have read a recent blog post from Amazon about how they achieved 90% cost savings by converting microservices applications into a monolith. This article from one of the early champions of microservices started a healthy discussion about microservices vs. monoliths. In this article, let’s compare these two architectural styles to make an informed decision on when to use which.

A little bit of history

Monoliths have been around since the dawn of software engineering. Applications are created as a single piece of code that includes all the modules that it needs to deliver all the required functionality. However, as the required functionality gets more complex, the monolith becomes more complicated; harder to modify, fix, and update; and requires all the teams working on it to coordinate to maintain it.

Service Oriented Architecture (SOA) emerged in late 1990s to provide some sort of independence to software development teams. It is defined as designing applications as a combination of independent services. These services handle independent business tasks and are black boxes to the outside world. They communicate through an enterprise service bus (ESB) to share resources and make updates.

Around the mid-2010s, microservices architectures inspired by SOA emerged. The idea was to create applications using independently deployable and individually scalable microservices that deliver business value and connect through the network. This isolation enables small teams to be responsible of each microservice and not be bounded by the constraints of other teams.

What are microservices good for?

Microservices are great for modularity. Each individual microservice is self-contained to deliver a function. If different applications need this function, they can reuse this black box microservice in their application without having to recode.

This modularity enables massive scalability. Because each microservice is independent of each other, they can individually be scaled up or down based on demand. For example, if there is a high load on analytics, the analytics microservices can be scaled up while keeping the other microservices the same. This ensures that analytics processing doesn’t get impacted by spikes in load and computing resources are increased only as much as needed. This scheme is especially good for applications that have spikes such as seasonality in their nature.

The separation of concerns unlocked with the modularity of microservices is also quite appealing. Microservices architecture enables changing components while the engine is running. It enables dynamic changes such as rolling updates or canary deployments without impacting any other service or having to wait for the whole application to be updated. This way, updates and bug fixes are deployed in a faster fashion.

Another benefit of microservices comes up in omnichannel applications. For example, a video streaming application can have different flavors of the UI microservice optimized for different devices, locations, or even users. With a microservices architecture, the application can reuse the same backend components with different frontends.

Microservices sound great, don’t they? Not for all applications. When you break down applications into smaller chunks, you have many more interactions that you need to worry about. These interactions are achieved through network calls, and you need to make sure that the services know how to find each other, they communicate securely, the network calls are authenticated, and the requests and responses do not get lost. These are some valid concerns that service meshes are there to resolve. However, you can see how complicated it gets when you replace method calls with network calls. Yes, you are gaining a lot in modularity, reusability, and scalability; but you should also consider what you are losing in terms of networking and security complexities and overheads. The scalability that you were hoping to achieve may be limited by the networking overheads you are adding.

What are monoliths good for?

Monoliths are great in the sense that they are self contained. They handle all the tasks in the monolith without being dependent on any other service or network call. And because they only expose functional endpoints, they have far fewer vulnerabilities than a mesh of microservices (I want to add “in an ideal world” here because no architecture style can protect you from bad coding that exposes more than it should). Therefore, there is a far narrower surface to secure, authorize, authenticate.

This simplified black box is great when you have a pretty stable workload. You can estimate the resources you need and build your infrastructure accordingly. This ensures that you have the computing resources you need for, say, your pretty consistent analytics load so that you don’t need to scale up or down dynamically, and you have reserved optimized resources for your application.

Monoliths are also better for applications that share a lot of resources. If different processes work on the same data, then keeping those data transfers close to the processes without having to go through the network would be more efficient. And if these processes also take place in cloud instances which are charged by the number of transactions, the resulting bill from network calls of the microservices could be quite high.

As confirmed by our customer interactions, most established organizations already have their applications coded in monolithic architectures. To convert these architectures into microservices requires a fundamental strategy shift, major rearchitecture, and massive resources. Sometimes, these resources are better spent optimizing the monolith, especially when the benefits of converting those microservices cannot be clearly communicated or there is not enough available talent well-versed in containers or serverless architectures in the organization to create a good microservices implementation.

How to choose?

The solution starts with defining the problem. What problem are you trying to solve by choosing either architecture? Just the exercise of answering this question will clarify your strategy going forward.

You think you want to switch to microservices? Ask yourself, what’s wrong with your monolith and emphasize the “what” part. Is it too slow? Is it consuming too many resources? What process is consuming those resources? Do you have to release frequent fixes and updates? What do you need to fix with those? Before jumping into a new architecture, spend some time on root cause analysis, and don’t fix what’s not broken. Look for solutions for what is broken. Maybe you need to spend some time optimizing your code, hire additional talent, or have a bug bash. Maybe it is indeed a microservices architecture that will solve your problem. If so, does the benefit of the rearchitecture outweigh the price?

You think you want to go back to a monolith? Again, are your microservices broken? Does your infrastructure cost too much? Is it too slow? Is it the processes in a microservice or the communications between microservices that is too slow? Do you have security issues? Does your team spend too much time recreating some microservices because they don’t know what’s out there?

A similar exercise awaits you if you are just creating a new application and deciding what way to go. Start your design with a monolith and as you refine it and figure out what issues there may be with your monolith that may cause you to switch your architecture. If there are no issues, then go with the monolith.

Software AG supports your decision

There is no winner in this battle of architectures. As you can see above, either style has its strengths and weaknesses, and neither can be considered better than the other. Microservices are no zombies, and monoliths are no monsters. Each use case should be considered individually to determine which style would be better for that application. The determination is up to the IT leaders who can evaluate the business case they are trying to solve, their constraints, and the talent pool they have in the organization.

Once you determine which architectural style makes more sense for your use case, Software AG is there to support you. Integration with its 600+ connectors to integrate custom, packaged, and mainframe applications and databases help you grow your application faster whether it is a monolith or is composed of microservices. For microservices specifically, we offer webMethods Microservices Runtime which is a lighter runtime that is optimized to host your microservices.

Implementing an API Management tool is crucial in this journey. It provides a layer of abstraction that will make you immune for future architectural shifts in your backend. webMethods API Management helps you manage, secure, and catalog the APIs you expose from your application. API Gateway can proxy your backend whether it’s composed of microservices or a monolith. We offer the webMethods Microgateway for securing and mediating microservices. Furthermore, webMethods AppMesh in the API Management suite was created specifically for microservices architectures and service meshes. It enables you to give application context to your microservices to convert them to, and manage them as, APIs. You can contact us to learn how we can help your organization to design, connect, manage, and secure the architectural style that fits best with your use case.