If you've read our piece about the habits engineers need to beat tech debt, you might recall Conway's law:
Organizations which design systems [...] are constrained to produce designs which are copies of the communication structures of these organizations.
It's one of the forces that can push us towards technical bankruptcy, because the systems designed by software engineers are constrained by their company’s organisational structure—over which they have little control.
The right way to fight these forces is to talk about tech debt across the whole company so that everyone can understand why it's vital to manage it carefully.
In this article, we'll go through the meta-problems caused by tech debt, and discuss exactly how they affect each area of any software business. This will give you the tools to alleviate a lot of the pressure your engineers have to deal with.
At a macro level, any growing software company can experience the tech debt caused by a codebase's ever-increasing entropy (i.e., the randomness in a system). Check out our article which outlines the simple reasons tech debt is inevitable for a deep dive into that topic.
Generally speaking, this growing entropy means equally increasing complexity. And complexity means lack of predictability.
The further into the future we try to predict, the less accurate our predictions will be. Combined with the fact that a complex codebase will take more time to modify, we've got ourselves a nice vicious cycle.
And in high-growth software organisations, this happens a lot faster than most people imagine.
Developers find poor quality code significantly slows them down within a few weeks.
Martin Fowler, Is High Quality Software Worth the Cost?
To help engineers break this vicious cycle, we built a free VSCode extension to continuously track and pay back tech debt. Get started now before it's too late!
Let's start with the obvious: Product development needs to be managed properly.
To create a superior product and win over a category, you need to keep a close eye on your customers' needs . . . and meet them quickly.
As Martin Fowler explains, 'Customers do care that new features come quickly . . . Better internal quality makes adding new features easier [and] therefore quicker and cheaper.' You can read more on this in his article.
As we discussed in our previous article on why tech debt is inevitable, the tradeoff we all face in every sprint is shipping new features vs. paying back some tech debt. Martin Fowler's point explains why, if we want to be able to keep shipping at pace, we cannot always choose the former.
If we succumb to the illusion that we can do both, we will go technically bankrupt, and we'll need six months to rewrite entire parts of our application. In reality, we can double this to at least a year, because a codebase with tech debt is highly complex, making it hard to estimate the scope of any modification to the code. And, of course, complex codebases resist change, which means everything takes longer.
Even if they know they have to bite—if not swallow—the bullet, company leadership really don't want to hear that 70% of engineering capacity needs to be allocated to a re-write. They might just decide to replace product leadership.
If you're a product manager and you'd like to avoid this, be sure to allocate a sensible tech debt budget in every sprint, so that engineers can pay back tech debt as they ship new features. Check out our article on how to stop wasting engineering time on technical debt for a guide to doing it. Do things right and you have a win-win situation—you'll avoid technical bankruptcy and ship features faster.
Sales teams like to win deals against a competitor by competing on features: 'Our software has more and better features than the competition, so you should buy our stuff.'
However, the reality is that early-stage software companies can rarely compete on features alone when they're fighting in an established product category. Incumbents will usually have a longer list of features.
One advantage that agile software companies have—or rather should have—is the ability to ship better features at a faster pace than their less agile competitors. So, as we've seen, if our codebase is riddled with technical debt, we won't be able to deliver new features at pace, bugs will get in the way of our users' experience, and the sales team will lose deals.
Salespeople who want to close more deals and get more commission (i.e., all salespeople), need to understand that Engineering cannot constantly cut corners. It will come back to bite everybody.
Successful marketing campaigns require a ton of coordination at a sustained, constant pace—we can't just get a feature in Techcrunch once a year and call it a day. We need to create an ever-improving growth engine to gradually build customer mind-share. And this takes years.
To do that, Marketing need product and feature release dates, and these release dates need to be met. In other words, we need predictability, because marketing campaigns require a lot of upfront work. There are numerous dependencies between marketing and the software release cycle.
If Engineering ships at a constantly sustained and predictable pace, Marketing can prepare accordingly. For Engineering to do this, technical debt needs to be managed carefully.
As for PR, I'll leave you with this banking horror storyabout how a database migration gone wrong allowed TSB customers to see and control other customers' bank accounts. It brought this behemoth of a bank to its knees, and as Nick Hammond, ex-global head of networks at Barclays and now lead adviser for financial services at World Wide Technology, explained: 'The crisis at TSB provides a great case study for the problems presented by the sheer complexity of many banking IT systems, and especially, the difficulty involved in changing them.'
That's what unmanaged tech debt looks like and it shows how much damage it can cause. You don't need to be a big bank for this to happen to your codebase. You might not make it to BBC News, but the consequences will be just as dire. Don't let it happen to you.
If Marketing wants product development to meet deadlines and avoid PR fiascos, they need to let go of the idea that engineers are wasting time repaying tech debt as they ship new features. In fact, they need to welcome tech debt payback and give Engineering the breathing space they need to deal with it, rather than pressurizing them to ship new features instead. It'll make all our lives easier.
A 'high quality code base' is the second most important thing Hacker News readers look for in a job, after 'work/life balance' (which is also impacted by tech debt). Put simply, engineers who are working on codebases riddled with tech debt are unhappy. They're spending too much time on features that should've been a formality. They don't improve at their job. They get bored. They don't grow. They leave the company.
Given how much it costs to hire new engineers, companies need to keep their staff turnover as low as possible. And the best way to do that is to carefully manage technical debt to maintain a healthy codebase.
There are many ways in which technical debt can cost us money: lost deals, customer churn, employee churn, lawsuits, and more.
However, there are a couple of issues that outweigh most of the others: engineering time, and the revenue costs of software delays.
The cost in engineering time is quite simple:
Engineers spend 33% of their time dealing with technical debt.
The Developer Coefficient (Stripe)
Think of it like this: if you pay your software engineers $100k, 33% of that goes towards dealing with technical debt. For a 50-person engineering team, that 33% is $1.65M/year. Stripe estimates this has a $3 trillion impact on global GDP. We don't need to dwell further on these numbers—they're clear enough.
On the other hand, the effect of delayed software product releases on monthly recurring revenue (MRR) is worth diving into. Let's quickly run through two scenarios where the monthly revenue growth rate remains constant at 15%, and the MRR secured on launch is $5k:
- The product launches in February (month 2 in the chart below)
- The product launches in April (month 4 in the chart below)
Shipping a mere two months later will cost our business 25% of the revenue we could've made over this selected period. MRR on month 24 would've been over 30% higher if we'd shipped just two months earlier and managed to maintain that shipping pace.
These figures are make-or-break for high-growth SaaS companies.
As Martin Fowler explains, a healthy codebase results in features being shipped faster, so it is crucial for engineering teams to have the purview to continuously manage technical debt as they build the product.
Poorly-managed tech debt leads to more bugs, more performance issues, and more downtime in the system.
This inevitably increases the load on QA, who are responsible for catching bugs before they get to the customer. It also affects Site Reliability, who maintain uptime and handle any performance issues. Ultimately, it means SLAs are unmet.
In turn, this causes more customer complaints, which increases the workload of Customer Support, Success, and Account Management, as unhappy customers require more help and attention. Worse, these customers might eventually leave.
There are a few commonly-held beliefs which we, as tech debt connoisseurs, need to debunk:
- That a healthy codebase isn't worth the cost
- That the cost of a healthy codebase is high
- That tech debt is only Engineering's problem
Managing technical debt is indeed within Engineering's remit, but clearly, tech debt also affects everything downstream too. The entire organisation needs to be aware of exactly how technical debt impacts it before it can truly grasp the perverse incentives it sometimes creates . . . which makes things more difficult than they need to be.
Provided engineering teams don't waste time dealing with, or tolerating, the wrong kinds of tech debt, a healthy codebase—where tech debt never gets out of hand—makes the addition of new features easier, quicker, and cheaper. The way forward includes continuous tech debt management, and engineering cultures that promote ownership to ensure long-term codebase health—and that's in everyone's best interest.
How does it work at your company? Let me know your thoughts in comments!