If you work in tech, you’ve almost definitely heard about microservices: the trendy style of software architecture where a system is split into multiple, independently-releasable services, that are modelled around business domains, and communicate via a network. Some people rave about all the amazing things they’ve achieved by using microservices’ benefits. Others rant about how much of their time it wastes and how much they hate it.
Like pretty much everything in tech, microservice architecture is a trade-off. Will it do great things for your organisation or not? That depends largely on how well set up you are to take advantage of the benefits and to absorb the costs.Microservice Architecture is a trade-off. Whether it's going to do great things for your organisation depends on how well set up you are to take advantage of the benefits and absorb the costs. Read more: Microservices: The Benefits and Costs Click To Tweet
If you’re looking to make a decision about whether to use microservices in your team (or reverse one!), here’s a list of many of the pros and cons which you’ll want to consider.
Benefits of Using Microservices
Microservice architectures are about having independently releasable services that are modelled around business domains. There’s a number of benefits to pursuing this style of software architecture. Here’s a really quick run-through of the main benefits people typically cite:
By assigning ownership of services to teams and enabling them to deploy services individually, they can release changes on their own chosen timeline. This minimises the need for coordination and negotiation with a wider group around deployments. That, in turn, can greatly reduce the time between making changes to the software and getting feedback about the value that has (or hasn’t) been delivered.
When designed well, a microservices architecture can insulate failures in one service from affecting the functionality of others, reducing the “blast radius” of any fault. When designed poorly, though, failures in microservice systems can be just as bad as with monoliths, and much harder to track down!
If you properly isolate services from each other using technology-agnostic interfaces, you can make use of different technologies in different services. That means, for example, you could employ a different programming language or framework where that will provide a benefit to the software. It also provides the opportunity for teams to experiment with new technologies with minimal impact on the overall system. These things are very hard to do when the whole system is built as a single monolith.
In contrast to a monolithic architecture, independent services allow you to increase the resources for only one part of your system, rather than needing to provision all instances of your monoliths with the resources to handle the most demanding peak loads.
Smaller, Simpler Codebases
Microservices is all about building smaller pieces of software focused on individual, cohesive business domains. For developers, this results in it being simpler to navigate and comprehend codebases.
Deploying individual pieces of software separately can mean many parts of the system can be deployed with little or no effect on customers, partners, or other internal systems. You may still have parts of the system that need extra caution to be applied when they’re deployed, but that caution no longer needs to get in the way of deploying everything else.
Some Costs of Microservices
So there’s no doubt there’s significant microservices benefits. If there weren’t it wouldn’t have become so popular.
But, of course, your team won’t get any of those benefits without huge changes to the way you do things. Some of those changes are going to require costly adaptations from your team.
Here’s some of the most frequently highlighted costs of moving to microservices:
Complexity Is Distributed
Ideally, any operation in your system will involve as few services as possible (because you designed your services around business domain boundaries, right?). But ultimately it’s a system, and not just a bunch of independent software, because the services interact. And understanding those interactions will be crucial to understanding your running system.
Infrastructure Needs More People-Power
Microservices results in more infrastructure, and often more types of infrastructure. That means more infrastructure work, so you’ll need more people working on infrastructure. As a result, you’ll have less people working on initiatives that add value to your organisation’s primary mission. Infrastructure work may happen mostly in a dedicated team, or it may be spread across all your teams and somewhat hidden. Either way, you’re going to be investing a higher proportion of your team’s time in infrastructure with microservices than without.
Increased Network Traffic & Latency
Splitting software into multiple services that communicate across a network obviously increases the network traffic and the bandwidth required to support that. It also adds significant latency to any synchronous process that needs to cross a service boundary. Your team will need to become proficient at recognising and minimising network latency. They’ll also need to learn techniques for avoiding latency when it’s introducing unacceptable delays.
New Network Failure Modes
Dropped packets, connection limits, read timeouts, DNS… There’s a myriad of ways any network interaction can fail. Moving to microservices will probably bring a lot of them into the scope of your developers’ daily work, but they weren’t something many of them would have had to think about while working in a monolith.
Monitoring Scope Explodes
Monolithic systems often have very few things needing monitoring – be that hosts, networks, databases etc. Even when there’s a lot of horizontal scaling, you may only be monitoring a very small number of types of thing, which means each new node added requires a fairly trivial change. With microservices, this is not the case. Instead, we’re creating many different types of things, each having some shared and some unique monitoring requirements, as well as having far more activity occurring across networks. All of that adds up to a need to invest far more into monitoring than a monolithic approach would require.
This is the flip side of the coin for the benefit of “Smaller, More Easily Understood Codebases“. There’s now not just one codebase, but many. What’s more, they integrate with each other across a network, not through function calls, so navigating between them will likely involve some manual searching rather than a simple click-to-browse. Again, a well-designed microservice architecture will minimise the number of services you need to look at in order to understand a single operation or workflow. But you’re not going to get away from sometimes needing to open up several projects in your IDE and trying to piece together how the code interacts.
More Build Pipelines
Independent releasability typically means independent build and deploy pipelines for each service. You might have had one or two people that looked after your build pipeline in the past. Now you’re going to need at least some expertise in each team to manage the pipelines for their services. You’re going to need a build / Continuous Deployment tool that allows your whole tech team to manage large numbers of pipelines and builds. You’ll want to figure how to get fast builds with minimal delays, but without wasting a lot of resources on idling servers. And you’re probably going to need to think about how standardised or bespoke you want your many build pipelines to be, and how you’ll manage any shared or mandated build patterns.
Testing Has To Adapt
Think about testing software, both automatically and manually. And now think about how microservices means changing your software architecture to be multiple different pieces of software, owned by different teams, that can be deployed independently, and which communicate with each other over a network using APIs and/or asynchronous messages. That means a lot of things need to change when it comes to how you’ll test your system and build confidence about its quality. Unit + integration tests alone aren’t going to cut it any more. Testing the full cycle of some features may become so complex that it’s impractical to automate it. And your quality advocates are going to need to learn about a whole new set of risks, failure modes, and tooling in order to deliver expert advice to the team.
Microservices introduces the possibility of thousands of different technologies across all of your services, managed in many different places. Most organisations won’t want a technology “free-for-all”, for a variety of reasons. That means you’ll probably need a way to record which technologies are currently recommended, deprecated, and being experimented with, and a process for moving things through that lifecycle. (A common approach is to maintain an internal tech radar.) At the very least, you’ll want to be monitoring all of your dependencies for security vulnerabilities. You might also want to consider nipping this in the bud by consciously choosing boring technology.
Increased Security Attack Surface
While there are many aspects to application and system security, the interface between the network and software is commonly a choke point where many security controls are implemented. Microservices architecture vastly increases the number of interfaces that the software exposes to the network. Because of that, microservices can enlarge the attack surface of the system by an order of magnitude. The end result is you’ll have a lot more security work to undertake in order to protect your system from attackers. The opportunity to use a variety of different technologies, and to be using various different versions of each one, also adds to the complexity of managing microservices security.
Comprehensive Data Analysis Is Harder
Monolithic applications usually have monolithic databases. Microservice architectures following best practices around information hiding almost definitely won’t. That means if you need to do some reporting that will combine data from multiple services, you probably won’t be able to just whip up a SQL query. Many organisations with microservices and non-trivial reporting requirements end up investing heavily in building a data warehouse or data lake.
Module Refactoring can get Harder
Few things make the costs of microservices apparent to software developers more than needing to refactor some functionality that is distributed across two or more services. In a monolith, shifting code around and just running the tests to check everything still works is child’s play. On the contrary, refactoring code between services is positively painful. It often requires unhealthy amounts of planning, cross-team coordination, multi-stage migrations, and the moving or re-writing of many existing tests. And all of that is just to make the system do what it already does but in a better way. Ouch.
Do Microservices Benefits Outweigh The Costs for YOUR Team?
So that’s the main microservices benefits and costs you’ll need to be aware of as you make a decision about whether or not to employ the approach in your team.
Okay – it was a lot. The list of microservices downsides may seem a lot bigger than the upsides. Depending on your team size and what you’re trying to achieve, though, the benefits of decoupling the work of individual teams may be huge, and the costs manageable as long as you’re aware of them.
So, knowing all this, is it the right decision for your organisation to take on microservices or not?
To answer that, we need a way to compare these benefits and costs to your organisational context. In the next post, I’ll be sharing 5 heuristics that you can use to get a feel for whether your team is in a better position to leverage microservices, or be inundated by them.