Complexity.

The most important concern when building a system that you want to grow and last is complexity. This applies to anything from roadways to fast food restaurants to spaceships. If you want your creation to scale and remain useful for as long as possible, you must declare war on complexity.

This article will focus on the topic of complexity within the context of software development and tech startups. In this industry, the term K.I.S.S. is very popular, and it means: Keep it Simple, Stupid. It sounds a little harsh at first, but as you read this article, the aggressive anti-complexity tone will make more and more sense.

When does something become complex?

Trying to quantify an inherently qualitative concept is hard. It’s like trying to define beauty with math. Luckily, what we mean by complexity in a system could also be quantified as “variables”. A variable is anything that must be able to change without the system ceasing to function.

Your car is designed to handle rain, but probably can’t be submerged in water and continue to function. How much easier would it be to build a car that couldn’t handle rain? No roof, no hood, no windshield wipers, etc. It would have been much easier. But the designers (and the market) decided that the product wouldn’t be attractive if it can’t handle rain. So they took on the added complexity to support that need. Since submerging your vehicle is not a common need, it’s generally not supported. Because doing so would increase the cost and weight of the vehicle for no good reason.

So, something is “too complex” when the added variables aren’t justifiable. There can be subjectivity here. Which ones are justifiable? You can find out by trying to pitch or sell the simpler product and react to feedback. This is why we build prototypes and MVPs. We’re trying to see if more complexity is justifiable. Would you buy a car that can’t get wet? No? Do you need to drive to underwater cities? Oh, there are no underwater cities? I understand. Your feedback is greatly appreciated.

How does complexity impact your product?

Let’s review the different ways that complexity impacts your product.

User Experience

Perhaps the biggest impact to your bottom line comes from the negative impact on User Experience (UX). Not all complexity impacts the UX, but much of it does. And often times, you’ll think that the complexity doesn’t impact the UX, but it actually does.

I have a good example from my time at Calendly. ( I’m sure I have dozens, but this is the first that came to mind. ) In order to reduce API calls to 3rd party calendar services, and to increase system performance, we wanted to cache the results of availability requests. How often does that data change, after all? The idea was to cache it for at least a few minutes. We would still double check at the time of booking a meeting, but we wanted to increase the performance of the calendar views. You wouldn’t think that would impact UX in any significant way, but it did, in a big way. It turns out, when our users made changes to their calendar, they would load one of their Calendly booking pages to check and see if the changes are being honored. This turned out to be a really common behavior. When they made changes to their calendar and reloaded the booking page, and didn’t see the impact, they became worried that they did something wrong. The added system complexity confused them and worsened the UX.

Your product is a tool for your users. They want to use this tool to solve problems in their life. The first step in using a tool is understanding how it will behave. We don’t tend to use tools if we can’t predict how they will behave, so we must understand them. When building your product, your job is to make it make sense to the end user. The most impactful way to do that is to reduce complexity.

New features

As we add complexity to a system, we’re adding variables which are different ways that the system can work and scenarios it must support. Each additional variable multiplies the supported use cases.

Let’s look at an example. I want to build a paperweight. It must hold down paper, which is easy. But my sales team has some ideas on how to make it better. They want it to come in a variety of shapes and colors. Sounds great! It’s our product, we can do whatever we want. Let’s offer 10 shapes and 20 colors. This is going to be great! Okay, so 10 shapes and 20 colors is 200 different SKUs. That’s a lot, but we can do it! The different shapes also mean different packaging concerns. The packaging design team came up with 3 different boxes that can handle all of the current shapes. Each of those boxes need designs for the appropriate shapes and each of the 20 colors. The box types are A, B, and C and handle shapes 1-3, 4-6, and 7-10 respectively. So Box A has 60 designs, same with Box B, and Box C has 80 designs.

Now, let’s add a new feature! We want just one more material option. So it was already a ceramic product, but we want a metal option. That’s just one more variable, but let’s see the impact. 200 SKUs become 400. The box design counts go from 60, 60, 80 to 120, 120, 160. All that from just one new variable. How about the next one, and the next?

As you can see, this paperweight somehow became extremely complex. The market probably won’t support the complexity of this business, so it won’t last very long.

Software companies generally keep adding and adding features indefinitely. This can’t be done if there isn’t a strong discipline of avoiding (and also removing) complexity at every opportunity.

Quality Assurance

No matter how your application is being tested, the multiplier effect described above applies to testing as well. A new supported scenario will roughly double the testing for anything that is affected by that variable.

For example, you have a product but you want to add billing tiers. That means each feature must be tested for each tier. The free feature must function correctly even if you’re on a paid plan. And the paid feature must gracefully direct the user to upgrade and must cease to function after a downgrade.

Get ready to hire much more people for the QA team and have your automated tests take much longer. All of these things will affect your bottom line.

Avoiding complexity

As stated earlier, it’s a great idea to think of complexity as something that must be justified. In my paperweight example, was market research done to determine that the customers won’t buy a paperweight in only one color? If so, what is the minimum number of color options that they will accept? Why are multiple shapes needed and how important is that?

You can also avoid complexity by reducing the states of the variables. What if the only colors were black and white? What shapes are the most popular and support the most use cases? If this had been done, they might have narrowed 20 colors down to 2, and 10 shapes down to maybe 2. That’s 4 SKUs instead of 200! Adding the new material in only one shape might have been a better idea. Now 4 SKUs become 6 instead of 8. This is so much more manageable!

When complexity can’t be avoided, it’s best to minimize it as much as possible.

Removing complexity

Just as important as avoiding it is removing it. Review the features and supported scenarios that add complexity to your system. Are there features that aren’t widely used? Payment tiers that aren’t attractive? Do you support devices and operating systems that are no longer popular? It’s a great idea to remove these things from your product on a regular basis.

Conclusion

With good habits and a healthy distaste for complexity, you’ll be able to build a system that your users will love, and will stand the test of time.

Go forth and remember to K.I.S.S.!

Next
Next

How I handle my own App Ideas