The complexity debt

Jordi Camps
5 min readJun 19, 2021

You have an amazing product.

It has been growing new features for a while now, reacting and adapting to customer needs.

Your users are thrilled: they frequently make Feature Suggestions to your website (or sales team), and are amazed at how customer-centric your company is: most of them are developed. They have a more and more customized experience every day.

That’s when things start to go wrong.

The agility and speed you used to be proud of, starts faltering. New features, even the most simple (does “that’s just adding an IF statement” ring a bell?), take forever to deploy. Bugs appear more and more often, so you need to spend more time on inefficient, manual testing. Pressure to release the next requirements build up and with the development team not able to deliver, frustration and burnout appears.

(By the way, there are a couple of affiliate Amazon links in this article, for books I really recommend)

How did we get here?

Now, if there was a simple answer, you wouldn’t have gotten there in the first place, would you?

Fortunately, the different reasons are all related. Things like:

  • You have been prioritizing features over refactoring, and accumulating technical debt. There’s no rules but most point to something like 15–20% of your time. This means after 5 years of near-to-zero refactoring, you’ve accumulated 1 full year of feature-freeze development. Scary, uh?
  • Coding mediocrity. Yes, having excellent developers in your team is important. No matter what coding norms and architecture your CTO establishes, mediocre and bad developers will add to the technical debt. Peer reviews help but, in the end, only up to a point.
  • Not mature capabilities. Yes, you should be doing Agile or Lean (I suggest you went the safe road and take SCRUM). Yes, you should be doing Devops. You should be at least doing Unit Testing but trying to reach the TDD utopia. This is not a religion, there are fact-based studies proving all of these are success factors for fast and robust software delivery. I strongly suggest you read the book Accelerate for an in-depth analysis.
  • Tightly coupled architecture. You reasonably started simple, with an MVC application, and a layered monolith API backend. New features were added with more SQL, services and business and database layers got mixed up. Spaghetti code is not friends with productivity, trust me. You’ll need to invest and find a way to (progressively) walk the path to hexagonal architecture, microservices, and some sort of event communication.
  • Misaligned teams. As the product grew, so did the team size. You knew about the 2-pizza-rule and started dividing the team but, did you divide it cleverly? The Team Topologies book by Matthew Skelton and Manuel Pais is a great starting point, if you still haven’t read it. The content of their website at https://teamtopologies.com/ is obviously more basic but also worth a read.

You might have noted all of the above are things you can work on — as an engineering manager, a CTO or a senior developer. But there is another, non-technical reason that causes this paralyses. And it’s probably the most critical.

The complexity cost

Let’s start with an example.

You are creating an expert system to diagnose simple health problems.

An expert system is “AI” for those of us who think this is a Boosted Decision Tree.

You start with a simple question: “do you have a fever?”. If so, you are ill. If not: you are OK. Couldn’t get much simpler than that: one question, two options. You code, you test both, you are done.

Then you add “Do you have a headache”? Two questions, 4 options. Still fairly easy. A user reports a bug, someone on the team quickly solves it.

Now add a few more questions. Do you a rash in your skin? Where? Do you have a sore throat?. You see, things are quickly getting out of hand.

What happens when there is a bug? You probably did not have test coverage for all the scenarios, so: how long does it take to debug the code? And to fix it, without breaking anything else?

I guess you get the point.

Yes, software architecture is there to help keep control of these things. So does an appropriate team organization, best practices such as devops, or good coding skills.

But nothing you do, can avoid one simple fact: As new features are added, complexity grows — often, exponentially.

In the end, you find yourself with a limited budget, which goes to pay the growing complexity mortgage of your project. With interests.

By the way, there is something which makes this still more of a problem: this is not a technical, but a business issue. New features are added to the backlog by Product Managers or POs who tend to put themselves “in the place of the customer”. And that, unfortunately, will eventually lead to complexity paralysis.

So, what should I do?

Here’s a few suggestions:

  • Say NO. Blocking new stuff from entering the backlog was never more important. Your company will need to take pondered decisions for every new feature. I don’t recommend anti-agile change committees, but a culture switch is a must.
  • Think twice. Many new features can be developed with some more branching on existing code. But good architectures and good coding will find ways to add them incurring in much smaller complexity costs. If you haven’t found the way to do that — think again.
  • Simplify your offering. You probably already have too many features, and they will be hard to remove — but not impossible. Every little victory will have a huge impact in the end.
  • Explain why. Business people have a hard time understanding one IF statement, let alone the exponential effect of complexity. But they’ve already seen the results, the slowness, the quality issues. Use their own experience to convince them, and remember to speak their language.
  • Give engineers authority. Make sure their opinions are considered in backlog items and priorities. Value cleaning technical debt and simplifying whatever can humanly be simplified.
  • Train your POs. Make sure they understand the costs of complexity, and have a long-term vision regarding the debts they are assuming for each and every item they add to the backlog.

And yes, you should also invest in refactoring, architecture, team organization, agile capabilities, and coding training. Complexity will grow despite the efforts above, and all these tools will be invaluable keeping its effects at bay.

--

--

Jordi Camps

Professionally, CTO and Product Owner at UVE. Personally, father, book devourer and an eclectic techie: domotics, data visualization, development... you name it