Stop Calling Everything Technical Debt
A client showed me their "tech debt backlog" with 214 items. Missing tests, outdated dependencies, bad naming, a database nobody understood, and an actual architectural shortcut from 2019. Lumping all of that into one bucket is why none of it gets fixed.
Last month a client walked me through their tech debt backlog. It lived in a Notion database with 214 items, color-coded by severity, tagged by team, and sorted by a priority score that someone had clearly spent a weekend building. It was meticulous. It was also completely useless.
The list included everything from "upgrade React from 17 to 19" to "rewrite the billing module" to "add input validation to the /users endpoint." A typo in a variable name sat three rows above "our event bus silently drops messages under load." They were all tagged the same way: tech debt.
When I asked the engineering manager how they decided what to work on, he shrugged. "We try to do one tech debt ticket per sprint." One ticket out of 214, chosen more or less at random, with no distinction between a five-minute rename and a three-month architectural overhaul.
This is what happens when a useful metaphor gets stretched until it covers everything and means nothing.
Ward Cunningham didn't mean this
The original technical debt metaphor, coined by Ward Cunningham in 1992, was specific. It described a deliberate decision to ship code that reflected your current understanding of the problem, knowing that as your understanding grew, you'd need to go back and rework it. The key word is deliberate. You took on debt consciously because shipping sooner had value, and you planned to pay it back.
That's not what most teams mean when they say "tech debt." What they usually mean is one of these things, all mashed together:
Bugs. A missing null check that causes a crash isn't debt. It's a defect. File a bug, fix it, move on. Calling it tech debt gives it a softer status it doesn't deserve and makes it easier to deprioritize.
Deferred maintenance. Upgrading Node.js, updating dependencies, rotating credentials. These are maintenance tasks. They're not the result of a trade-off you made — they're the result of time passing. Your car's oil change isn't "automotive debt."
Code that was never good. I see this constantly. Someone wrote a 400-line function with nested conditionals six layers deep, no tests, and variable names like tmp2. That's not debt. Debt implies you once had something of value and borrowed against it. This code was never solvent. It's just a mess.
Intentional shortcuts. This is the only one that actually fits the metaphor. "We hardcoded the tenant ID because we only have one customer right now, and we'll make it configurable when we need to." That's real technical debt — a conscious trade-off with a known payback condition.
Missing capabilities. "We don't have automated database migrations" or "our test suite doesn't cover the payment flow." These aren't debt either. They're gaps in your engineering practice. Important to address, but lumping them with everything else means they compete with typo fixes for the same one-ticket-per-sprint slot.
Why the distinction matters
I've watched this play out at half a dozen clients. The catch-all "tech debt" label creates three problems.
First, it makes prioritization impossible. When a critical architectural flaw and a renamed variable are both "tech debt," there's no framework for deciding which matters more. Priority scores try to solve this, but they're arbitrary without meaningful categories. A severity-3 bug and a severity-3 maintenance task don't require the same response.
Second, it lets teams avoid the hard conversations. Saying "we have a lot of tech debt" is comfortable. Saying "our payment service has a race condition that could double-charge customers, and we've known about it for four months" is uncomfortable. The vague label provides cover.
Third, it trains product teams to ignore engineering concerns. If every sprint has one "tech debt" ticket and nothing visibly improves, product managers learn that tech debt is a bottomless pit and stop allocating time for it entirely. I've seen this cycle kill engineering morale at three different companies.
What I tell clients
I tell them to stop using the phrase entirely. Instead, I ask them to categorize their backlog into specific buckets:
Defects go into the regular bug tracker and get prioritized like any other bug. No special label, no special process.
Maintenance gets a recurring time allocation — not a sprint slot but a percentage. Something like 15-20% of engineering capacity dedicated to upgrades, dependency updates, and infrastructure upkeep. It's not optional and it's not negotiable.
Architectural decisions that need revisiting get written up as proposals with clear costs and benefits. "Rewrite the billing module" isn't actionable. "The billing module processes refunds synchronously, which blocks the API thread for 3-8 seconds. Here's a proposal to make it async, estimated at two weeks, which would eliminate our most common timeout" — that's something a product team can evaluate.
Code quality issues get addressed in context. When you're working on a file and the function is a mess, clean it up as part of the work. No ticket needed. This is just professional software engineering.
Note
The spreadsheet that got smaller
That client with the 214-item Notion database? We spent half a day recategorizing everything. 31 items were actual bugs that went into the regular tracker. 47 were maintenance tasks that got a dedicated weekly slot. 89 were code quality notes that we deleted as standalone items — they'd get handled as part of regular development. 12 were architectural decisions that got written up as proper proposals.
That left 35 items of genuine technical debt: intentional shortcuts with known payback conditions. Thirty-five is a number you can actually manage. The engineering manager told me two months later that they'd cleared 20 of them.
Nobody misses the spreadsheet. What changed wasn't the volume of work — it was the ability to have a real conversation about what matters and why. "We have 214 tech debt items" is a cry into the void. "We have three architectural shortcuts in the payment path that will block multi-currency support" is a sentence that gets budget.
The metaphor was good. We just stretched it until it broke.