The hidden cost of complexity
Why should I read this?
To better understand the real and deadly cost of complexity. By noticing our biased perception of both simplicity and complexity. And also by modeling complexity to uncover some of its characteristics. Mainly it’s exponential nature.
Simplicity, in my opinion, is the most important principle of software development. Here, I said it. It’s that simple :)
Do you think the same? Let me tell you why I believe it.
Two sides of the same coin
Simplicity is undervalued
We often fail to see the hidden beauty of simplicity. As if we take it for granted. It’s very easy to miss out on the ingenuity it introduces. This is because a simple solution is obvious to explain and understand but often not to discover. It is difficult to take pride in something that once explained, seems trivial. Even if it might have required a monumental effort to uncover. After all, people often judge results, not the way to get them. But to better understand the value of simplicity we need to look at it the other way around. Hello, complexity.
Complexity’s true cost
I argue that complexity is a disease. A fatal disease. It’s been added to in small doses by every decision we make. Slowly but surely these have an accumulative impact on the body they invade. The velocity of change slows down as if invisible weights are being added to a runner’s legs. Eventually, it might even reach complete stagnation. In the worst cases, a painful intervention (like a rewrite) is the only way forward.
Complexity is admired
Why is this scenario so common? To answer this question we need to understand that we are biased toward complexity. This is because we are taught to appreciate complexity. Take the Great Pyramid of Giza as an extreme example. It’s considered the last standing member of the Seven Wonders of the Ancient World. A remarkable and impressive building. But being blunt, it’s just a tomb. The pharaoh simply needed a place to be buried. Let’s say that this was his intention from the building (ignoring religious or political motivation). Then, a simple grave would have been enough. Something similar to what heads of state receive these days. Yet we admire the building and its complexity. We don’t see it as a waste of resources that could have been invested elsewhere.
And here comes the great irony:
We admire complexity and avoid simplicity, while we should admire simplicity and avoid complexity.
Can you estimate the impact of complexity? What does it do to your system or organization? Maybe it feels that it’s just too abstract even to approach this topic. Let’s see if we can analyze together the hidden cost of complexity, and how to fight it.
We need to build for ourselves a mental model that will give shape to this elusive foe. This will serve as a cornerstone in our approach toward complexity.
Any chain is built by connecting links. Let’s take for example a random software company system and try to describe it with chains. Links would be system components (e.g., microservices). A chain would be comprised of system components that are coupled in any meaningful relationship (e.g., microservices that communicate with each other). The system then can be represented as a collection of chains. That’s it, enough with definitions.
Let’s view a concrete example. Say we have two microservices that communicate with one another. They are both links in our chain. In addition, they run on a cloud provider. The cloud provider is another link. And finally, the services are deployed using some single CI/CD infra. Yet, another link. We now described a chain of four links. So far so good.
Complexity will hit you hard when links start to have more than a single state. For example, let’s assume one of the microservices is being migrated to a new major version (e.g., having breaking changes in the API). During the migration process that link will simultaneously have two states. As if our chain forked into two “phantom chains”. Furthermore, if we support a multi-cloud architecture and have 2 different cloud vendors another link has more than one state. But now our original chain has been transformed into 4 phantom chains. During the same time, the infra team started A/B testing the CI/CD infrastructure. The 4 doubles to 8. This grows exponentially.
An edge case that leads to system failure can now be triggered in only one of the phantom chains. For example, a bug that is triggered by an API call to the newly migrated microservice. But only if it was deployed using the new infra on the first cloud. The stage is set. And guess what, it happens sometime around 2 AM waking the on-call engineer. Leading to yet another postmortem.
The more chains you have and the longer they become, the risk for an exponential explosion of phantom chains increases.
Let’s notice some interesting behaviors that arise from this modeling:
- Complexity impact- Adding the same amount of complexity to a complex system yields a higher impact than on a simple system. This is due to the exponential factor of complexity.
- The complexity paradox- An effort for reducing complexity, in the long run, will probably add complexity in the short run. This is since making changes that involve migrations adds more states to existing chains’ links (visible in the example above). This can generate a feeling among people that our efforts for reducing complexity are failing when they are actually not.
In this post, I addressed one type of complexity. However, complexity can come in many different shapes and forms. Listing a few:
- System complexity- As we described above. The complexity of the system components and their interactions.
- Product complexity- From products to services. Breaking it down to features, UX, flows, and their interactions.
- Organizational complexity- From the organization structure to its processes and governance.
- Code complexity- Not just the classical time and memory definitions of computer science. But also other aspects such as clean code.
While the mental model above won’t fit all types of complexity, some attributes of complexity can still be valid. For example the exponential nature of it. Thus, we should aim on fighting complexity on all fronts.
In my next post, we will discuss ways to combat complexity. E.g.:
- Considering it in our decision-making process
- Continuously and proactively engaging with it
- Making sure we are not over-simplifying things
Complexity is often admired by people. Yet we often miss that it has a deadly side as well. We usually fail to see its cost until it becomes too late, mainly because it’s an abstract and elusive concept. Modeling complexity and its exponential nature allow us to be aware of the dangers ahead. Emphasizing the crucial importance of simplicity.
A side note on the mental model of complexity chains: A better model will probably be a graph (the classic computer science one). Where each system component is a node/vertex. An edge between nodes marks that those system components are connected in some relation. Then our chains from the previous example will be cliques in a graph. But this is just too complex. My main idea in this post is to preach simplicity, not to build an accurate model for complexity. It’s true for systems as it is for blog posts. Hopefully, an inaccurate yet simple model will help reinforce the takeaway message. Complexity has an exponential nature. Be aware of the danger it poses.