Technical Debt

The tradeoff between shipping a faster, less-ideal solution now and the ongoing cost of maintaining or fixing it later — much like financial debt.

What is it?

Sometimes a team deliberately ships the quick, hacky version of a feature to hit a deadline, fully intending to come back and do it properly later. Sometimes a team doesn't even realize the shortcut is a shortcut until much later, when a "simple" change turns out to be surprisingly hard because of decisions made months ago. Both situations are examples of the same underlying idea, borrowed directly from finance: technical debt.

Just like financial debt, taking on technical debt isn't inherently bad — borrowing money to seize a real opportunity can be the right call. The shortcut that ships a feature two weeks earlier than the "proper" version might win you a customer, validate an idea, or hit a deadline that genuinely matters. The debt itself is often a reasonable trade.

The part that has to be taken seriously is the interest: the ongoing extra cost that accrues for as long as the debt is unpaid. A messy, hastily-built module doesn't just cost what it cost to build — every future change that touches it takes longer, every bug in it is harder to track down, and every new engineer takes longer to understand it. Left alone indefinitely, that interest compounds: the mess makes the next shortcut more tempting (because doing it properly next to existing mess feels pointless), which makes the codebase harder to work in, which makes rushed shortcuts more likely — a debt spiral.

The discipline isn't "never take on technical debt." It's knowing you took it on, being deliberate about it, and having a real plan — and ideally a written record, like an ADR — for paying it down before the interest outweighs whatever the shortcut bought you.

Explain like I'm 10

Financial debt: borrowing money to open a store sooner (a reasonable trade) still means paying interest every month until it's paid off. Ignore the debt for years and the interest payments alone can exceed what you originally borrowed — the same dynamic hits a codebase's 'quick and hacky' shortcuts left unaddressed.

Examples

Taking on technical debt deliberately, and marking it

// TECH DEBT: hard-coded to a single currency (USD) to hit the launch
// deadline. Proper fix: support the Money value object with currency
// conversion once international launch is scheduled. Tracked in JIRA-482.
function calculateTotal(items) {
  return items.reduce((sum, item) => sum + item.priceInCents, 0);
}

The shortcut is real (no multi-currency support), but it's explicit, explained, and linked to a tracked follow-up — the team knows exactly what was borrowed and has a plan to pay it back.

The same shortcut, left as invisible debt

// No comment, no ticket — just a plain-looking function
function calculateTotal(items) {
  return items.reduce((sum, item) => sum + item.priceInCents, 0);
}
// Six months later, "add support for EUR customers" turns into a much
// bigger project than expected, because nobody remembered — or ever
// knew — that currency was hard-coded everywhere this function is used.

Identical code, but with no acknowledgment that a shortcut was taken. The 'interest' here isn't just the cost of the eventual fix — it's the extra cost of first rediscovering that debt exists at all.

How it works

Technical debt accrues "interest" in very concrete ways: slower feature development in and around the affected code, a higher bug rate because the shortcut didn't account for edge cases properly, and a steeper learning curve for anyone new touching that part of the system. Paying down the debt (refactoring, rewriting, adding the missing tests) is the "principal payment" — it costs real time up front but removes the ongoing interest. Deciding when to pay it down is a genuine engineering-management tradeoff: pay too early and you might rework something that ends up not mattering; pay too late and the interest may have already outweighed the benefit the shortcut bought.

Why does it exist?

The term exists because "just write it properly the first time, always" is not a realistic option in a world with real deadlines, uncertain requirements, and limited time — sometimes a fast, imperfect solution is legitimately the right call. Naming the tradeoff as "debt" gives teams a shared, honest vocabulary for discussing shortcuts without either pretending they don't exist or treating every shortcut as an unforgivable mistake — it reframes the conversation as a financial tradeoff to be managed, not a moral failing to be denied.

When to use it

Taking on technical debt deliberately makes sense when the short-term gain (hitting a real deadline, validating an uncertain idea before investing further, unblocking a critical launch) clearly outweighs the interest you'll pay until it's addressed — and especially when you have a genuine, realistic plan to pay it down. It's also reasonable to accept some debt permanently on code that's genuinely low-stakes or likely to be thrown away soon anyway.

When not to use it

Avoid taking on debt silently, without acknowledging it, tracking it, or telling anyone — that turns manageable debt into an invisible trap for whoever encounters it next. Also avoid taking on new debt in an area that's already deep in unaddressed debt with high interest — that's the point where a deliberate repayment effort, not another shortcut, is what's actually needed.

Common mistakes

  • Treating all technical debt as universally bad, and refusing any shortcut even when the situation genuinely calls for shipping something imperfect quickly.

  • Taking on debt without recording it anywhere (a comment, a ticket, an ADR), so it becomes invisible and gets rediscovered the hard way later.

  • Letting debt accumulate indefinitely with no repayment plan, until the 'interest' — slower development, more bugs — becomes the team's biggest ongoing cost.

Practice exercises

  1. Easy:

    Describe a shortcut you've taken (or seen taken) in real code, and identify what the ongoing 'interest' on that shortcut has been.

  2. Medium:

    Write a short technical-debt tracking note (like the comment example above) for a hypothetical shortcut: a search feature that only does exact string matching instead of fuzzy search, taken to hit a launch date.

  3. Hard:

    Propose a lightweight process a small team could adopt to make sure technical debt is recorded and periodically revisited, rather than silently accumulating. Consider how it would connect to sprint planning or code review.

Interview questions

What is technical debt, in your own words?

The ongoing extra cost incurred by choosing a faster, less-ideal solution now instead of the more thorough one — similar to financial debt, where the shortcut is the 'principal' and the extra cost of working around or fixing it later is the 'interest'.

Is taking on technical debt always a bad decision?

No — it can be a reasonable tradeoff, such as shipping a simpler solution to hit a real deadline or validate an idea, as long as the debt is acknowledged, tracked, and there's a realistic plan to address it before its ongoing cost outweighs the benefit it bought.

What's the danger of undocumented technical debt specifically?

It becomes invisible — future engineers don't know a shortcut was taken at all, so they can't factor it into their plans, and it tends to be rediscovered only when it causes an unexpectedly difficult bug or feature.