Everyone who writes code lives with technical debt—the shortcut that solved yesterday’s problem but collects interest today. The most common mistake is not creating debt; it’s treating all debt as a sin and wanting to refactor everything, always, right now. This guide is for anyone who feels the code “rotting” but still needs to keep delivering: the goal is to replace guilt with criteria.

What technical debt is—and what it isn’t
Technical debt is the gap between the solution you delivered and the solution you would have postponed delivery to “do properly.” It comes from conscious choices (“let’s hardcode this now and generalize it later”) and also from decisions we didn’t even realize we were making—lack of context, a short deadline, or knowledge that only arrived afterward.
What isn’t technical debt: ugly code that works and no one needs to touch, or an architecture that is simply different from your preferred one. Debt is whatever increases the cost of changing the system in the future. If no one is going to touch that section anytime soon, the interest is low—and you may not need to pay it down at all.
Not all debt is bad: the interest analogy
Think like someone taking out a loan. Debt can be foolish or leverage, depending on what you do with it and how high the interest is. A shortcut that lets you validate an idea weeks earlier may be worth far more than the refactoring it postpones. The problem is almost never the conscious shortcut; it’s the forgotten debt, quietly accumulating interest until the day when any small change becomes a nightmare.
The right question is never “is this perfect?” It’s “how much does it cost to live with this—and is that cost increasing?”
The quadrant: four types of debt

A simple way to look at debt is to cross two questions: was the decision intentional or accidental? And was it prudent or reckless?
- Intentional and prudent: “We know this isn’t ideal, but we need to launch; we wrote down why.” This is good debt.
- Intentional and reckless: “We don’t have time to do it right”—repeated forever, without a plan. This is where the danger lies.
- Accidental and prudent: “Now that we understand the domain, we know how we should have done it.” Pure learning: healthy and expected.
- Accidental and reckless: the team didn’t know what it didn’t know. Address it with study, review, and mentoring—not blame.
The label matters because it changes the conversation: prudent debt is managed; reckless debt is prevented.
Criteria for deciding: pay down, schedule, or live with it

Before opening your IDE to “fix” something, run the code through three filters:
- Frequency of change. Do you touch this code every week, or has it been frozen for months? Debt in hot code charges high interest; debt in dead code is almost free.
- Blast radius. An isolated shortcut behind an interface is easy to replace later. A shortcut that has leaked into ten places is already costing you dearly.
- Risk. If the worst case is a cosmetic detail, live with it. If the worst case involves data, money, or security, raise its priority—even if the code appears to be “fine.”
With these filters, the decision almost makes itself:
- Pay it down now when the code is hot, the blast radius is large, and the risk is real—preferably by refactoring alongside the next feature that touches that area.
- Schedule it when the cost is moderate and predictable: record it, make it visible, and treat it as real work, not as something to do “when there’s time” (there never is).
- Live with it when the code is cold and isolated: accept it consciously and move on.
The classic pitfall is the opposite of this: the giant, heroic weekend refactor, disconnected from any delivery. It often introduces more risk than it removes.
How to document it and negotiate with the team and the business
Debt that exists only in your head doesn’t exist for the rest of the team—and disappears when you change projects. Leave a trail where the team already looks: a short comment explaining the decision and the trigger for revisiting it, a backlog item describing the cost in clear language, or a note in the task that created the shortcut.
And here’s the part almost no one teaches: you don’t sell refactoring by talking about code. Outside engineering, no one cares about “coupling.” Translate it into risk and cost of change. “This shortcut makes every change to this screen take three times as long and causes production breakages” is a sentence that product and leadership understand—and prioritize.
Closing the account
Technical debt isn’t the villain of the story; it’s a business tool like any other. Mature teams don’t have zero debt—they know exactly which debt they carry, why they accepted it, and when they intend to revisit it. The next time you feel guilty about a shortcut, change the question: instead of “is this right?”, ask “is this cost increasing—and is it worth paying down now?”. That change alone already separates people who put out fires from those who make decisions.

