Technical debt explained: what it is, what it costs, and how to pay it down
Mosaddik Billah 5 min read

On this page
“Technical debt” is what developers call the cost of shortcuts in code. Like financial debt, it’s not always bad: borrowing can get you somewhere faster. But it charges interest. Every new feature takes a little longer, every change carries a little more risk, until the team spends more time working around old decisions than building new things.
This post explains it for both developers and the people who pay for their time.
The metaphor, and why it fits#
Ward Cunningham, who coined the term, compared shipping not-quite-right code to taking out a loan. You get the feature sooner, which can be exactly the right call. But until you go back and fix the code to match what you’ve since learned, you pay interest: extra time and risk on every change that touches it.
Two things follow from the metaphor:
- Some debt is a good deal. Launching a simple version before a trade show, to test whether customers want it, is a sensible loan.
- Unpaid debt compounds. New code gets built on top of the shortcut, so fixing it later means fixing more.
What it looks like in practice#
You rarely see technical debt directly. You see its effects:
- “Small” changes take days, and estimates are always wrong.
- Fixing one bug causes another somewhere unrelated.
- Only one developer understands a part of the system, and everyone is nervous when they’re away.
- Releases are rare and stressful, done late at night, with manual checks.
- New developers take months to become useful.
Behind those effects, the usual causes:
- No automated tests, so every change has to be checked by hand, or isn’t checked at all. See the testing pyramid.
- Copy-and-pasted code, so a rule lives in five places and gets fixed in four.
- Tangled structure: business rules mixed into pages and route handlers, everything depending on everything. See how to structure a backend project.
- Outdated dependencies, frameworks or platforms several major versions behind, with known security issues and painful upgrades.
- A data model that no longer fits, such as a database designed for one shop now serving five. See database design basics.
- Missing knowledge: no documentation, and decisions nobody remembers the reasons for.
Not all debt is the same#
A useful way to sort it, from Martin Fowler’s “technical debt quadrant”, asks two questions: was it deliberate or accidental, and was it prudent or reckless?
| Reckless | Prudent | |
|---|---|---|
| Deliberate | “We don’t have time for tests.” | “We’ll ship now and clean this up after launch.” |
| Accidental | “What’s a database index?” | “Now we understand the problem, we’d design it differently.” |
The bottom-right kind is unavoidable and healthy: you always learn as you build. The top-left kind is the one to stop.
How to pay it down without stopping everything#
A total rewrite is tempting and almost always a mistake. It takes longer than planned, the old system keeps changing meanwhile, and the new one quietly loses rules the old one handled. Pay it down steadily instead:
- Make it visible. Keep a short list of known debt, each with what it costs (“every change to checkout takes 2 extra days and breaks something about once a month”). Debt described in time and risk gets prioritised; debt described as “messy code” doesn’t.
- Pay interest first on the busiest code. Messy code that nobody touches costs nothing. Clean up the parts you change every week.
- The boy scout rule: leave code a little better than you found it. When a feature touches a messy area, tidy that area as part of the feature.
- Reserve regular time. Many teams spend 10 to 20% of each cycle on maintenance. Steady and boring beats an annual “clean-up sprint” that gets cancelled.
- Add tests before you change things, so you know the clean-up didn’t break anything.
- Replace large parts gradually. Build the new version alongside the old one and move traffic over piece by piece, so there’s never a risky big switch.
How to take on less of it#
- Decide deliberately when to take a shortcut, and write down what you’d do properly and when.
- Keep a minimum standard that isn’t negotiable: tests for money and data, code review, dependencies updated regularly.
- Keep things simple. A lot of debt comes from complexity added “for later”: extra layers, abstractions and services (see monolith vs microservices) that make every future change harder.
- Write down important decisions, one paragraph each: what you chose, what you rejected, and why.
For business owners: questions to ask#
You don’t need to read code to manage technical debt. Ask your developers:
- “What slows you down the most right now?”
- “What part of the system are you most nervous about changing?”
- “If we spent two weeks on maintenance, what would get faster or safer?”
- “How long would it take someone new to make their first change?”
Clear, specific answers are a good sign. And if the answer to the last one is “months”, or one developer is the only person who can work on the site, that’s debt worth paying down before it becomes a business risk.
If you’ve inherited a Wix site or app that’s hard to change, I can review it and fix what matters most as part of Wix Velo development. How to brief a Wix developer helps you describe the problem.
Comments