Technical Debt Is a Loan, Not a Sin
Most teams treat technical debt as something to feel guilty about instead of something to manage. That framing is why it never gets paid down.
Nathan Levine
4 min read

"Technical debt" gets used as a synonym for "code we're embarrassed about." That's the wrong frame, and it's the reason most teams never actually manage it — you don't schedule time to deal with shame, you either avoid looking at it or you do a guilt-driven rewrite that creates a new mess. Debt is a much better metaphor than people give it credit for, if you actually treat it like debt.
A loan, taken on purpose
Real financial debt isn't inherently bad — it's a tool. You take a loan to ship a store before the holidays, to hit a fundraising milestone, to capture a market window that won't wait for the "correct" architecture. That's a legitimate trade: speed now, in exchange for interest paid later. The problem was never taking the loan. It's taking it without knowing you took it, or without ever intending to pay it back.
The same is true in code. Hardcoding a value instead of building a config system to hit a launch date is a loan. Copy-pasting a function instead of extracting a shared abstraction, because the right abstraction isn't obvious yet, is a loan. Both are fine — as long as someone knows the loan exists.
Where it actually goes wrong
Debt isn't the failure mode. Undisclosed, unmanaged debt is:
- Debt nobody logged. The engineer who took the shortcut leaves, or just forgets, and six months later a new hire is confused why a piece of core logic is duplicated in four places with no explanation.
- Debt with no repayment plan. "We'll fix it later" without a ticket, an owner, or a trigger condition is not a plan — it's a wish. It gets refinanced indefinitely until it's load-bearing enough that nobody wants to touch it.
- Interest compounding silently. Every new feature built on top of a shortcut makes that shortcut more expensive to remove later, the same way unpaid interest grows the principal. A quick hack in month one can become a six-week untangling project by month twelve, without anyone deciding that should happen.
Managing it like debt, not like sin
A few practices that treat this as the financial problem it actually is:
- Log it the moment you take it. A ticket, a
// TODOwith a linked issue, a line in a debt registry — anything that survives the memory of the person who wrote it. Untracked debt is the only kind that's actually dangerous. - Attach a reason, not just a description. "Hardcoded because we needed to ship by Friday" is more useful later than "hardcoded value here," because it tells the next person whether the constraint that justified it still applies.
- Budget time to pay it down, deliberately. Teams that treat every sprint as 100% feature capacity never pay debt down — it only gets serviced during a crisis, at the worst possible time and interest rate. A standing allocation, even 10-15%, keeps the balance from becoming unmanageable.
- Prioritize by interest rate, not age. The oldest debt isn't always the most urgent — the debt sitting under the code that changes most often is accruing the most interest, and that's what should get paid down first.
The reframe that actually helps
Calling it debt instead of sin does one important thing: it takes the emotion out of the conversation. Nobody needs to defend a decision that was correct at the time, and nobody needs to feel behind for having some on the books. What matters is whether it's tracked, whether the interest rate is understood, and whether there's an actual plan to pay it down before it compounds into something that blocks the next thing you're trying to ship.
Debt-free codebases aren't the ones that never took a shortcut. They're the ones where every shortcut was a decision someone can still see.


