Skip to main content

Command Palette

Search for a command to run...

Tech Debt Is How You Learn Your Codebase Is a Business Asset

Updated
11 min read
L

Backend engineer focused on real-world software. I care about clarity, architecture, and decisions grounded in reality. Strong on Java, AWS, automation and AI workflows. I write about engineering without dogma.

In some companies, “technical debt” doesn’t even exist as a real concept. Mention it in a meeting and you get the look: this is a nice engineer word, but it doesn’t apply here. The product ships, revenue grows, incidents are “manageable”… so what exactly is the problem?

The problem is simple: if nobody in your company can say roughly how much tech debt you have or where it lives, you’re not running a tech organisation. You’re running a business that happens to have people writing code. And that distinction matters a lot more than most leadership teams realise.

In a real tech company, the codebase is part of the asset being built and valued. Technical debt is not an aesthetic concern or a perfectionist’s hobby; it’s part of the quality of the thing investors, partners, and customers are implicitly trusting when they decide to rely on your product. At some point, someone serious will look under the hood. And, oh boy… will they absolutely have an opinion.

This post is not a step-by-step “how to fix all your tech debt in 90 days”. Instead, I want to reframe the discussion: from “engineers whining about refactors” to “leadership understanding tech debt as asset quality and governance”. How to map, prioritise, and systematically pay down debt in a messy microservice ecosystem is a topic for several other posts.


1. What I Actually Mean by “Technical Debt”

Before we go any further, it’s worth being precise about what I mean by technical debt.

Technical debt is not just “ugly code”. It’s a trade-off: you borrow time today by making the code harder to change tomorrow. When you touch that code again, you can either “pay interest” (move slowly, fight the mess, ship less) or pay down principal by cleaning it up and making future changes cheaper. The key question is whether that trade-off was intentional or just happened to you.

There are two useful axes to think about technical debt:

  • Deliberate vs inadvertent:
    Did we know we were taking on a shortcut, or did this emerge because we didn’t understand the problem, the domain, or good design practices at the time?

  • Prudent vs reckless:
    Given what we knew, was the shortcut a reasonable bet, or were we simply gambling that “future us” would somehow sort it out?

Martin Fowler’s “Technical Debt Quadrant” describes this nicely: you can have deliberate–prudent debt (a conscious bet to ship faster now), deliberate–reckless debt (we know this is a mess and we’re still doing it), inadvertent–prudent debt (we learn later that there was a better design), and inadvertent–reckless debt (we don’t know what we’re doing and we’re joyfully piling up landmines anyway).

If you like the simpler framing, you can compress this into “good” vs “bad” debt:

  • Good debt is known and chosen. You understand why it exists, where it lives, and roughly what it would cost to clean up.

  • Bad debt is unknown or denied. Nobody remembers deciding to accept it, nobody can point to where it is, and everyone is surprised when it explodes.

This is not about bad people, blame, or public shaming. Every non-trivial system will accumulate some form of technical debt, even with excellent engineers. The real problem starts when an organisation refuses to talk about it, won’t name it, and never treats it as something you can reason about and decide on. That’s the pattern this post is about.


2. “We Don’t Do Tech Debt Here”

In some organisations, the phrase “technical debt” doesn’t just fall flat. It triggers mild defensiveness. You bring it up in a planning meeting and you get variations of the same response:

“We don’t really have that here.”
“Right now we just need to ship.”
“Our problem is speed, not tech debt.”

On paper, these companies often look quite “modern”. They might have microservices, Kubernetes, CI/CD, feature flags, even Sonar wired into the pipeline. There’s a dashboard somewhere showing code smells, coverage, and duplicated code. You can demo it to visitors. It looks like a team that takes quality seriously. They probably also have a big whiteboard wall absurdly filled with coloured post-its.

And then you talk to the engineers and you hear the real story:
*“Yes, Sonar is in the pipeline… but we ignore the results.”*
*“The quality gate is technically there, but it’s ignored so builds can get through.”*
“When the build fails on ‘too many issues’, someone just lowers the threshold so the board stays green.”

That’s what it means, in practice, to “not do tech debt”. It’s not that the concept doesn’t exist. It’s that the organisation is structured so that any signal about code health is soft, optional, and ultimately irrelevant to the real game: shipping features that move the metrics everyone is actually measured on.

Again, this is not about bad people. The engineers are usually doing their best under constraints they didn’t design. Leadership is usually under pressure from investors, customers, and competitors. Given that setup, ignoring tech debt is a perfectly rational local decision, until you zoom out and realise that, over time, you’re optimising for “never hearing bad news about the codebase” rather than for building a reliable, understandable asset.

If mentioning technical debt consistently gets you the same reaction as suggesting a new office plant, that’s your culture speaking. The message is clear: this is not something we take into account when we make real decisions.


3. Tech Company vs Company with an IT Department

There’s a sentence I keep coming back to when I look at how organisations treat technical debt:

“You’re not a tech company, you’re a company with an IT department.”

That sounds arrogant if you leave it there, so let’s be precise. I don’t mean “real tech companies write in language X” or “use Kubernetes” or “do microservices”. I mean something much simpler: in a tech company, engineering can win against short-term business pressure in the painful moments. Not always, not by default, but sometimes. In a company with an IT department, things like tech debt are always a secondary concern. They never actually win.

You can usually tell which one you’re in by looking at a few concrete decisions:

  • When a critical feature depends on a part of the system everyone calls “the big ball of mud”, does anyone seriously consider fixing the mud first?

  • When the team says, “We can ship this in three weeks on top of the mess, or in six weeks if we clean it up properly”, is the six-week option ever chosen?

  • When engineers bring up structural issues (observability gaps, inconsistent APIs, nonexistent tests) are these treated as real inputs to planning, or as background noise?

None of these are about perfectionism. They’re about whether the organisation is willing, at least occasionally, to say:
“We’ll accept slower delivery now because the long-term health of the codebase matters.”

Technical debt alone doesn’t define whether you’re a tech company. Every serious product has debt. But how you respond when someone points at that debt is a very strong smell. If the answer is always some version of “not now”, you’re sending a clear signal: the code is not part of the asset; it’s just plumbing behind the real business.

And once you see it through that lens, the earlier behaviour makes perfect sense. Of course Sonar results get ignored. Of course refactors never make the roadmap. Of course nobody can tell you where the main pockets of risk are. In a company that only has technology, but isn’t really about technology, that’s not a bug. It’s the expected outcome.


4. Good Debt, Bad Debt, and the Appendix Story

Not all technical debt is bad. In fact, some of the best engineering decisions I’ve seen produced very deliberate technical debt.

Years ago, I heard a metaphor from Neil Murray, co-founder and former CTO of Mimecast, that has stayed with me ever since. Someone in an internal meeting asked about an ugly, obsolete part of the system that nobody had bothered to remove. Why was this still there?

Neil’s answer was roughly:
“I also have an appendix. I don’t use it for anything. It can get infected. It has no real value. But I’m not rushing to have surgery just to remove it. It’s a known risk with a known cost, and right now, it’s not worth the operation.”

That’s good technical debt.

At some point in the past, that code was necessary for the product to exist at all. Maybe it had to run on a single machine in a cupboard, or support a legacy customer that kept the lights on. Today, the code no longer adds value. It might even look embarrassing to anyone seeing it for the first time. But it’s known, it’s understood, and the team has made a conscious decision: the cost and risk of removing it right now is higher than the benefit.

Good debt looks like that:

  • Someone can tell you why it exists.

  • Someone can tell you roughly what it would cost to remove or fix it.

  • Someone owns the decision to keep it for now.

Bad debt is different. Bad debt is when you wake up in surgery surprised you even had an appendix. Nobody remembers choosing this. Nobody can tell you what breaks if you touch it. Everyone assumes someone else, at some point, must have thought this through.

From the outside, both types of debt can look the same: ugly code, weird modules, legacy services nobody wants to touch. The difference is governance. In one case, the mess is a conscious trade-off you’re managing. In the other, it’s just a pile of hidden risks you’ll discover at the worst possible time.

The goal is not to eliminate technical debt. That’s impossible and, frankly, undesirable. The goal is to shift as much of it as possible into the “we know about this and we chose it” bucket and minimise the amount of “joyfully piling up landmines and hoping future us doesn’t step on them.”


5. Technical Debt as Asset Quality, Not Engineer Aesthetics

This is where the conversation usually breaks down. For many leadership teams, “technical debt” sounds like an argument about taste: engineers wanting “cleaner” code the same way designers want “nicer” fonts. If you frame it like that, you’ve already lost. Aesthetics will always lose to revenue.

The more honest framing is this: technical debt is part of your asset quality. If you’re a tech company, a large chunk of your valuation is based on an assumption that your product can keep evolving at a reasonable cost and risk. Your codebase is where that assumption either holds or quietly dies.

At some point, someone outside the team will test that assumption. It might be an investor’s technical advisor, a potential acquirer, a strategic partner, or a very senior candidate deciding whether to join. They won’t care that you “move fast” if every change comes with a side order of fear. They will look at how predictable it is to add features, fix defects, and onboard new engineers. And, oh boy… will they absolutely have an opinion.

From that perspective, unmanaged technical debt isn’t just “the code is a bit ugly”. It shows up as:

  • Changes that should be simple taking months because nobody understands the impact.

  • Entire areas of the system that only one or two people dare to touch.

  • A roadmap that is secretly constrained by “places we’re too scared to work in”.

  • Incidents that keep happening again and again because the real fix lives in the messy part of the codebase nobody wants to open.

None of this appears in a pitch deck. But all of it is part of what a serious third party is implicitly evaluating: How much of this company’s future is hostage to the way the code was written under pressure five years ago?

You don’t need a perfect codebase. What you need is a codebase whose weaknesses are known, owned, and intentionally managed. That’s what separates “engineers arguing about pretty abstractions” from leadership taking asset quality seriously.


6. Where This Post Stops on Purpose

If you’ve read this far, you might be expecting a neat framework: five steps to get your tech debt under control, three metrics to track, a template for your next planning meeting.

That’s not this post.

Starting to deal with technical debt in a real, messy microservice ecosystem is hard. It’s political. It touches roadmaps, headcount, hiring, promotions, and vendor choices. You don’t fix that with a single workshop or a clever spreadsheet. You certainly don’t fix it by telling engineers to “just refactor a bit when you have time”. It requires a deep change in how the organisation thinks and talks about its own systems, and that kind of change has to grow organically, not be imposed by a memo.

What I wanted to do here is simpler and, in my experience, more fundamental:

  • Stop treating technical debt as an engineer’s aesthetic preference.

  • Start treating it as a question of governance and asset quality.

  • Make it possible (culturally and politically) to point at debt, talk about it, and make conscious trade-offs.

The “how” deserves its own space: how to map the mess, how to decide what to ignore, how to run a 12–18 month debt programme alongside aggressive product goals without burning everyone out. That’s several posts, not a closing section tacked onto this one.

For now, I’ll leave you with a simpler question:

If someone asked you today where your main pockets of technical debt are, and what you’ve consciously decided to tolerate, would you have a clear answer or would you just hope nobody ever asks?

More to come on this topic… probably on a Tuesday, in your favourite blog you somehow keep reading.