Back to Insights

Technical Debt Isn’t the Problem — Ignoring It Is

By Tony
opinion
engineering
Technical Debt Isn’t the Problem — Ignoring It Is

Technical Debt Isn’t the Problem — Ignoring It Is

Let’s start with something that might sound a little bit uncomfortable. If your codebase has no technical debt, one of two things is true:

  1. You haven’t shipped anything meaningful yet
  2. You’re lying to yourself

Technical debt is not a failure mode. It’s not something that happens when a team “loses discipline” or “cuts corners”, it’s a natural by-product of building software in the real world. It's a pragmatic response to commercial constraints.

And yet, teams still talk about it like it’s a problem to eliminate. That's not necessarily true - the problem isn't debt, it's ignoring it, not tracking it, not knowing when to deal with it - that's where debt becomes rot.

The myth of “no tech debt”

There’s this persistent idea that good engineering teams maintain clean, pristine codebases. That if you just hire the right people, follow best practices, and write “proper” code, you can avoid technical debt altogether.

You can’t.

You especially can't when you're in a fast moving start-up with commercial constraints. You don't always have the luxury of spending £100k on engineering the perfect solution and taking 3 months when your bootstrap runway is 6 weeks. Sometimes the pragmatic solution needs to win.

Every meaningful system carries trade-offs:

  • Speed vs quality
  • Flexibility vs simplicity
  • Time-to-market vs long-term maintainability

Technical debt is just the accumulation of those trade-offs over time.

In my previous start up, which was successfully acquired in 2025, we made a huge trade off for the first few years. Whilst this isn't strictly technical debt in terms of pragmatism around the code or architecture it was certainly a huge element of product capability debt.

The application was massively configurable for customers to define their very specific data capture and workflow requirements. For the first ~3 years, we had absolutely no user interface for our customers to configure it!

When we sold deals, we sold 500 seats. Of those 500 users, maybe 5 would need to configure the system - the power users. We focussed on building what the regular user's needed first.

Until we had a design/admin tool, we would engage with the customer during onboarding to configure their system for them , which also allowed us to book additional revenue via services. That wasn't the strategic direction we'd aimed for, but establishing ARR by delighting the actual users rather than the power users configuring it was the right move at the time. It also allowed us to refine the configuration meta models without committing to any UX and tooling for it, meaning when we then built the admin system later, we were doing so on a proven underlying model.

In the early days, you should be taking on debt. You’re optimising for learning, for speed, for survival, for establishing the all important "product market fit". As much as you'd like to think you do, you don’t even know what the product is yet, so over-engineering is actually the bigger risk.

The problem is that many teams never update that mindset.

They either:

  • pretend the debt doesn’t exist, or
  • swing too far the other way and try to eliminate it entirely

Both approaches are flawed.

Intentional vs accidental debt

Not all technical debt is created equal, and this is where most teams go wrong. There’s a world of difference between debt you choose to take on, and debt you just sort of end up with.

Intentional debt is when you know exactly what you're doing. You make a call that something isn’t ideal, but it gets you where you need to be faster. It’s a trade-off, and more importantly, it’s a visible trade-off. You know where it is, you know why it exists, and you have a rough idea of when it might come back to bite you.

Accidental debt is different. That’s the stuff you didn’t plan for. It creeps in through rushed decisions, unclear requirements, or just not quite understanding the consequences at the time. It’s the “we’ll just do it this way for now” decisions that never get revisited.

And this is where things start to feel off.

Because intentional debt feels like control. Accidental debt feels like friction.

It’s the difference between:

  • choosing to move fast
  • and wondering why everything feels slow

Most teams treat all technical debt the same, and that’s the mistake. Because the way you manage intentional debt is completely different to how you deal with accidental debt.

Why most teams get this wrong

Technical debt is one of those topics that gets surprisingly emotional. Engineers see messy code and want to fix it, founders hear “we need to refactor” and immediately see time, cost, and risk to delivery.

So what tends to happen is teams drift into one of two camps.

Either they ignore it completely — “we’ll deal with it later”, which almost always means never. Over time things slow down, bugs creep in, and confidence in the codebase starts to drop, but it happens gradually enough that no one really calls it out until one day all the engineers are too scared to touch that brittle code.

Or they go the other way and try to fix everything. Clean it all up properly, get back to a “good place”. That usually turns into a rewrite, and rewrites have a habit of taking longer than expected, delivering less than hoped, and completely killing momentum.

Neither approach works. They’re just two different reactions to the same misunderstanding — that technical debt itself is the problem.

It isn’t.

A quick sidebar on re-writes - Dont do it!

Unless it's an absolute wreck, unsalvageable or it's a prototype / proof of concept, do not entertain the idea of a complete re-write.

The pursuit of perfection results in the second-system effect - the dangerous tendency for a second, successor system, to become bloated, over-engineered and slow. The time and cost to carry out a re-write will typically be high and leave you wide open to potential disruption where you're overtaken and lose market position.

Instead, catalogue your debt, write up a plan and deal with it incrementally and methodically over time as part of wider work. Ensure that engineers refactor often, that they leave the codebase better than when they found it, and start striking off that debt as you go. For an established system with debt, a complete re-write is often commercial suicide.

(For more info on the second-system effect - see "The mythical man-month" - Fred Brooks, 1975)

How to manage debt without killing velocity

If the goal is to eliminate technical debt, you’re going to fail. The goal is to stay in control of it and that starts with visibility. Not in a heavy, process-driven way, just a general awareness across the team:

  • where things are a bit fragile
  • what’s slowing you down
  • where there's friction adding features or fixing issues and that friction keeps coming up again and again

Once you’ve got that, it becomes a prioritisation problem rather than a philosophical one. Some of it is worth fixing, some of it isn’t, and that decision should be driven by impact, not principle. If something is actively slowing the team down, it’s probably worth addressing. If it’s sitting there quietly not causing any issues, it might never need to be touched. Perhaps more importantly - if it's causing a high volume of tickets for the support/CS team, indicating user frustration - it probably needs sorting out.

The biggest mistake teams make here is trying to carve out time to “deal with technical debt” as a separate activity. That’s how you end up with debt sprints that either get cancelled or achieve very little.

The better approach is to deal with it as part of normal delivery. Improve things as you touch them. Make small, continuous improvements rather than big, disruptive ones. It’s less satisfying from a “clean code” perspective, but it’s far more effective in the real world.

What founders need to understand

From a founder’s perspective, technical debt is often misunderstood. It’s either seen as a sign that something has gone wrong, or as an excuse from the engineering team to slow things down. In reality, it’s neither.

Technical debt is just the result of prioritisation decisions. Every time you choose speed over perfection, you’re likely taking on some level of debt. That’s not a failure, it’s often exactly the right call.

The important thing isn’t avoiding it, it’s understanding it. Where is it? Why does it exist? What risk does it introduce? If you can answer those questions, you’re in control, but if you can't, well, that's when it becomes a problem.

And this is where a lot of friction between founders and engineering teams comes from. One side is thinking in terms of delivery and momentum, the other is thinking in terms of sustainability and risk, and neither side is wrong - the gap is usually just a lack of shared understanding.

Final thoughts

Technical debt isn’t something you eliminate - it’s something you live with, and manage, for as long as the system exists.

The best teams don’t have the least amount of technical debt. They have the best understanding of it. They know where it is, why it exists, and when it’s time to do something about it.

Everything else is just noise.

Stop trying to get rid of technical debt.

Start treating it like what it actually is — a tool you use to move faster, as long as you stay in control of it.