Complexity

If there’s a single concept that can change your life and career, it’s understanding the nature of complexity: where it comes from, why it’s bad, and how you can avoid it.

This article was inspired by my personal struggles with complexity and experience with adopting minimalism into my life. It primarily focuses on complexity from a systems lens and tries to inform through examples in software and the natural sciences, although the concepts are generally applicable anywhere you look.

The goal of this article is to help you recognize complexity in your life. Understanding complexity provided me with a new mental model for me to view the world, helping me to achieve more with less. I hope it does the same for you.

But before we can understand complexity, we first need to understand systems.


What is a system?

Much like a network, systems are a series of interconnected components that interact with each other to achieve some unified purpose.

A lot of things are systems. Your digestive system is a system composed of multiple organs that talk to each other using hormones with the purpose of breaking down food into basic nutrients. A company is a system of employees that work together to make a profit. The economy is a system. A software application is a system. Your body is a system, the Earth and Universe are also systems. Systems are often composed of multiple sub-systems, which are themselves systems of systems – ad infinitum.


Where does complexity come from?

Complexity is a natural and self-emerging property of all systems in the universe. Systems that are simple are predictable. But as they grow with the introduction of new components, some components will at times interact with each other to produce unintended side-effects. Examples include bugs in software, side effects from drugs and medication, or conflicts in the workplace.

Any system that is continuously changing will become increasingly complex. This is due to entropy, a fundamental force in the universe that brings disorder and chaos. Our bodies are a prime example of this as mutations in our DNA accumulate over years of living that lead to the breakdown of homeostasis resulting in aging and death. Parts of the system that were designed to work one way break down, and after some critical point the entire system falls apart. There is only one correct configuration and an infinite amount of incorrect ones. Life itself is a constant struggle against the forces of entropy.

Complexity also compounds. The number of lines of code tends to scale exponentially over time1, along with the number of bugs. Tech debt due to a few poor decisions when starting out will snowball until it becomes unmanageable. The more things you add to a system, the more things can go wrong. Adding a new component to a 1000-component system may result in 1000 new possible interactions that can backfire.


Why complexity is bad

Since systems are created to achieve a specific purpose, we like them to be predictable. The entropy introduced by complexity is anything but predictable, often leading to unintended side effects.

Such is the case every time we add add a new library to our codebase, when we download a new app on our phones, or when we hire a new member on our team. Doing so increases the complexity of the overall system and increases the chance of undesirable interactions. A new library may have existing bugs that propagate into our code, we might download a new social media app for some perceived utility only to find ourselves in a time-sink, we might make a bad hire that can ruin an entire team.

If you’re designing an app, trying to cram in too many features can disorient users from finding the core features that they truly care about. If you try to cram the maximum amount of words in your resume, a recruiter may find it hard to read and toss it out. If your landing page reads like an essay, users will simply skip over all the text.

We unconsciously see many of the problems caused by complexity as normal. We don’t give much thought to these unintended behaviors because we are often tunnel visioned onto the problem itself instead of recognizing complexity as the source.


Complexity is invisible

Because we cannot see complexity, it often slips by unnoticed. This is very dangerous and often leads to the downfall of a system. Large companies can build up so much complexity to the point where a simple feature that would normally take a day to build ends up taking multiple months. Debugging becomes impossible, the pace of innovation slows down, and eventually a lean startup with a much faster iteration speed comes along and takes the throne. Complexity is the leading reason why established companies die of irrelevancy. There’s a reason why Apple, a company known for its minimalistic practices, has survived for so long and continues to thrive.

In my line of work, I notice that most frontend developers spend the bulk of their time wrangling with React state, debugging type issues, in config files trying to get libraries to play well with each other, resolving package.json version conflicts, or working around some bug or limitation in a library. Due to all of this overhead, how much time is actually spent on the product itself? We’re often told that we should use this framework and that library because it’s “modern” and has so-and-so benefits but don’t give much thought its long-term inconveniences. Does it really make sense for someone’s personal website to have 200x more code than what’s needed to send a spaceship to the moon?2


Dealing with complexity

This isn’t to say that we should avoid large and complex systems entirely. Many systems, like our body, are very big and complex, but also necessarily so. Small systems are predictable but have a limit on their impact. Larger systems are necessary and complexity is not something you can avoid.

But we should strive to never make something more complicated than it needs to be.

  • When coding, write as little code as possible and abstract only when needed
  • When writing, be concise and use language that anyone can understand
  • When designing, boil the problem to its core and find the simplest solution
  • In life, find the things that matter to you and ignore everything else

When adding components to a system, ask yourself if it’s critical to the functioning of the system or not. Don’t neglect thinking about the consequences of a new component, and only adopt it into the system if the benefits greatly exceed the potential downsides.

Take some time every now and then to declutter. Clean out your room, refactor your code, trim your paragraphs. Practicing minimalism is a conscious practice that requires constant revision, thoughtfulness, and dedicated effort. But it is much more effective than any medicine or quick hack to make yourself less frustrated and a lot happier.

In reality, many things are simpler than they seem. It doesn’t take much to build a good app, to write well, or to live a good life. Yet somehow, we always overcomplicate things.


Further Reading

The content in this post is inspired by many articles and books I’ve read in the past. If you’re interested in diving deeper, here are some resources you might enjoy:



  1. Source: Code size in space missions, ScienceDirect
  2. Code for the original Apollo-11 mission (1.1 MB), GitHub
    Size of Create React App (219 MB), flaviocopes.com