Peter Marklund

Peter Marklund's Home

Fri May 28 2021 10:54:52 GMT+0000 (Coordinated Universal Time)

The Maintenance Burden of Microservices

Autonomous teams is a popular idea in the industry today that tends to be associated with microservices. Autonomous teams fully own their services and are trusted to make their own decisions. The idea is that this will make them more motivated and productive. I fully support this idea. There are many other factors that drive microservices adoption such as scalability, performance, fault tolerance and the architecture of cloud infrastructure (i.e. the emergence of serverless functions etc.). However, multiple challenges arise when a team goes from owning a handful of services to owning dozens. Unfortunately I believe that when a team splits up its services on a micro scale it is setting itself up for a heavy maintenance burden.

When creating a new microservice we as developers tend to feel really good about ourselves and we can be quite productive. We enjoy how seemingly isolated and modular microservices are and we enjoy doing greenfield development. If we are lucky we may even get to use our favorite language, framework, coding conventions, or infrastructure. We feel free as we are seemingly no longer bound by legacy systems. Let's imagine a difference scenario down the road though where we find ourselves having to do maintenance of a large number of microservices that have accumulated over several years and generations of developers with different preferences - many of which have left. This scenario is obviously not quite as attractive...

Here are some challenges with microservices:

Let's review the action points and decisions involved in creating a new service:

Now suppose you want to make a change in any of the areas listed above. Let's say you want to change cloud provider, or build pipeline, or the framework that you use, or upgrade the version of your programming language. Instead of being able to make this change with one or a handful of PRs you end up needing to make dozens of PRs. Or maybe you don’t have time to create all those PRs and then your services grow more inconsistent over time and this is the most likely scenario.

Let's think about everything that is not core business logic in a service. In other words let's think about the incidental complexity, the implementation details, and the boilerplate. To make things concrete I will use a Node.js API hosted on Github and deployed with Docker on AWS as my example. Here is an incomplete list of boilerplate for such an API:

What is the ratio of essential business logic code to boilerplate in a microservice? Well that varies but it's not uncommon for there to be at least as much boilerplate as business logic.

As a small development team I think the goal should be to only be maintaining a handful of services. Sometimes architecture will force us into having more services or the team may have too much on its plate but we should try to avoid that if we can.

In this post I've mostly talked about the duplication problem but another important aspect is that microservices comes with distributed computing and a fundamental increase in complexity. Ironically this may actually be one reason why developers are attracted to this architecture. After all, developers tend to be drawn to complexity and the challenge of solving hard problems.