Is your application too difficult to manage? Do changes take dozens of developers hundreds of hours to execute, and frequently result in downtime across all your site’s functions? It sounds like you have a monolith! A monolith is one of the three main software architectures that define most applications. Whether you’ve intentionally set out to create a monolith or not, it’s worth at least weighing the pros and cons of the different architectural approaches and deciding which one makes the most sense for your applications. The proper design pattern can save your organization time and money, and can make your engineers a whole lot happier. But how will you know which is right for you? Read on to figure out if a monolith, microservices, or self-contained system makes the most sense for your development team.
Let’s start by discussing monoliths. A monolith is the “default” software architecture. If you didn’t set out with a plan before you started coding, you probably created a monolith. As the name implies, this style of application is one big codebase: All functions and features of your application are together, frequently dependent on each other, and split among dozens or hundreds of different files. Though it’s the oldest architecture, there are clear advantages to monoliths, which is why many very successful organizations stick with them. Unfortunately, there are also a lot of drawbacks.
- Initial development is fast
It’s relatively easy to add new features and functionality to a monolith because there’s no question about where anything should go—the answer is inside the monolith. Easy!
- There’s less complication around crosscutting concerns
If you have a workflow that touches every part of your application—like charging user credit cards and generating shipping labels—a monolith makes implementing it extremely simple. All your data is right there and you can act on it immediately. Compare this to complicated message passing, queuing strategies, and trying to find canonical sources of truth, and you can see why monoliths are so enticing.
- All concerns only need to be addressed once
Do you need to set up logging, rate limiting, or security features for your application? Luckily for you, with monoliths you only have to do it once. When it’s done the first time, it’s done for good.
- It’s difficult to change
Once the monolith starts to get big, it can be incredibly difficult to alter, and generally the complexity of changing anything is exponential to the size of the application. With so much code and so many paths in the system, reasoning about changes can be very difficult and even a small commitment can have a huge unforeseen impact. This makes the engineers who were originally responsible for the monolith very, very important for maintaining it, which can be a problem organizationally.
- Scaling is tricky
When your monolith scales, you can’t just scale parts of it—you scale all of it. If your monolith will only run on very powerful servers, you’re paying for a lot of server time to potentially scale a very small part of your application. This can drain your operations budget very quickly, and yet most of the capacity you’re paying for you won’t even effectively use.
The takeaway: Most developers consider monoliths the way of the past. Some still embrace them, but you’re much more likely to run into teams espousing the value of microservices.
By comparison, microservices offer many benefits, but also a few real drawbacks. A microservice is just a single part of your larger application, presented as an application in and of itself. For example, if you run a web store, your inventory tracking, label generator, and credit card charger may all be independent microservices responsible for just one concern—they’ll have their own database and their own API for communicating with other parts of your system. By working together, they provide a seamless experience to the user, but behind the scenes they’re all independent.
- It’s easy to maintain and understand
Each application has one primary purpose. Reasoning about an application’s behavior is usually quite simple if it’s built with a laser-like focus on that purpose. Developers can easily jump in and out of projects, leading to less information siloing. Even better, development tends to be fast; testing suites are comprehensive and quick-to-run; and with the proper tools, zero downtime deployments are easy. Microservices are a joy to code for.
- Better isolation leads to less downtime
When an application fails, the other applications around it are unaffected. So even if your order taking system is down, customers can still check the status of their existing orders or possibly even browse the store while being none the wiser. And if you need to scale, you can scale only an overwhelmed system without needing to pay for capacity you won’t use.
- It requires lots of infrastructure automation
Microservices are operationally complex. Instead of just one application, you’re running a dozen, or several dozen, or even hundreds of them. You can’t manage them on just one server, and you can’t deploy them by hand. You need a deployment and development process that automates the complexity away, or else it’ll drown your engineers.
- Crosscutting concerns are difficult
Getting data from service to service in a consistent, sensible way can be very difficult. Usually if you find yourself passing a ton of messages from one place to another (say, user objects all over the place) you probably need a new microservice responsible just for the canonical representation of those messages (a user microservice, that could also possibly handle authentication). This is quite a bit harder than the equivalent for monoliths, however, where all the data is “just there.”
The takeaway: Despite their flaws, microservices are generally considered better than monoliths architecturally: They are easy to improve and manage, and operations difficulties can be passed to a DevOps team experienced in handling them. But if you want a middle ground between the two, you’re probably looking for a self-contained service.
A self-contained system, the new architectural kid on the block, is partway between a monolith and a microservice. It wraps a number of microservices to appear as one entity, but is still smaller to reason about than a monolith. If you have a number of components that are very tightly coupled—too tightly for a microservice to make sense—then what you want is a self-contained system. Self-contained services are very new. Their differences from microservices and monoliths are a matter of degree, not kind.
- You get the best of both worlds
With a self-contained system, you gain the benefits of monolithic simplicity: Crosscutting concerns are easy to handle, and you also get the ease of coding and deploying that microservices enjoy. You don’t need to worry about message passing or canonical data representations, since all data the app cares about is internal. What could be easier?
- It’s architecturally difficult to define
The line between a microservice and a self-contained system is muddy, if it even exists. Many services you may want to include inside a self-contained system actually fit better outside of it. Then you’ll be forced to do a painful separation process to break out your service. And there are precious few resources to tell you if a feature should be inside or outside of your self-contained system.
The takeaway: Ultimately, because self-contained systems are so new and so little guidance exists, microservices are a better choice for development teams—at least for right now. That said, self-contained systems are perfect for people looking toward microservices. Breaking up a monolith along sensible seams and creating self-contained systems is a great first step to the eventual adoption of microservices across your organization.
Though self-contained systems are hot and new, and microservices are popular and cool, it’s impossible to definitively say which architecture is the right one for your application. Many of the most popular applications on the internet are monoliths, and are still extremely successful; there’s something to be said for reliability and simplicity. Only by weighing the pros and cons of the different software architectures will you be able to choose the right one for your organization. Whichever you choose, embrace it intentionally and learn everything about your choice, and you’ll be able to support it and enhance it moving forward.