The socio-technical aspects of microservices: cognitive load
This article is part of the series “the socio-technical aspects of microservices”.
Microservice architectures are terrible in many ways. Things that are straightforward in a monolith often turn into complicated issues. All of a sudden, you have to abandon some of your most powerful tools: transactions, consistent backups and automated refactoring.
It takes quite a bit to make up for the loss of these tools.
If we want microservice architecture to be successful, we need to play out all of its strengths. One of those strengths is linked to cognitive load.
Cognitive load?
I first came across this concept in the book “Team Topologies: Organizing Business and Technology Teams for Fast Flow” by Matthew Skelton and Manuel Pais.
In essence, cognitive load refers to the amount of stuff you have to hold in your head to perform a task.
The more stuff you need to hold in your head, the higher the cognitive load. The higher the cognitive load, the more difficult the task gets.
When you’ve got to rename a local variable, you don’t need much more than an understanding of the enclosing function.
But when you’re trying to improve the performance of an entire system, you need to have the system’s entire architecture in your mind.
Some tasks require such an enormous amount of knowledge that they basically become impossible. If you’ve ever tried to untangle a distributed monolith or to understand an involved race condition, you know exactly what I mean.
Going beyond our cognitive limits
If we want to keep our systems evolvable, we have to keep them small enough to fit into our heads.
This is easy to accomplish while our systems are still in their humble beginnings. But as our systems age, as they evolve, and as we add more elements to them, they grow more complicated. Our most successful systems grow so much that they surpass our cognitive limits.
If you’ve ever contributed to an old monolithic system together with some 200 other developers, you probably know what I mean.
Once a system has grown beyond comprehension, we will start to see negative consequences:
First, the boundaries in our system tend to dissolve. Those boundaries where useful to make sense of the system, because they added some structure to them. But eventually we lose sight of the forest for the trees. As we forget the big picture, our boundaries become meaningless, so we ignore them.
Second, it becomes difficult to predict the effect of our changes. Is this part of the system connected to this other part or not? There is only one way to find out: experimentation. Every time we make a mistake, the system will suffer from a fault.
Third, things take longer than they used to. This is because people are afraid to break something, so they double and triple check. From this point on, the system has become effectively unmaintainable. Eventually, progress grinds to a halt.
Microservices reduce cognitive load
If we want to avoid all of this, we should strive to keep cognitive load as low as possible.
This is where microservices can help us!
If we break down our large monolithic system, the individual pieces can become small enough to fit into our heads again.
This frees our teams from the need to understand the entire system in all of its detail. Instead, teams can take ownership of individual microservices and develop expertise in just that one area.
As teams become more familiar with the services they operate, they begin to be more confident about the changes they make. What’s more, the team can build a shared mental model. Consequently, the changes they make will be less faulty.
This way, a lot of the negative effects of a large monolithic system will disappear again. And it all begins with a simple change: making the system comprehensible by breaking it into pieces.
This wraps up our discussion of cognitive load. In the next article, we will talk about why microservices should facilitate learning.