Eslam Hamed
Technical Lead & AI Solutions Architect
Building enterprise AI systems, cloud platforms, and production-ready software
Technical Debt Is a Loan: Explain It With Interest, Not Code
A product owner asks you a fair question. Last year, adding a new discount type to checkout took two days. This year a similar change is estimated at two weeks, and the request is no harder. What changed?
The honest engineering answer is a list. The pricing code has grown special cases. The tests are slow and nobody trusts them. The one person who understood the tax rules has moved to another team. Every item is true, and to the product owner every item sounds like an excuse, because none of them comes with a price.
That is how technical debt usually gets explained: in the vocabulary of the people who write the code, while the cost lands on the people who wait for it. Treat the question like any other "how long will it take?" and answer the decision behind it. Here the decision is whether to keep paying for this part of the system as it is, or to pay once to change it.
What Ward Cunningham meant by debt
The metaphor comes from an experience report Ward Cunningham wrote for OOPSLA in 1992, on the WyCash portfolio management system. He compared shipping first-pass code to borrowing: a small loan makes a team faster, as long as it is repaid soon with a rewrite. The trouble is the loan nobody repays. In his words, "Every minute spent on not-quite-right code counts as interest on that debt." He warned that the load can bring entire engineering organisations to a halt. Two days becoming two weeks is how that starts.
Years later he explained the metaphor again in a video, transcribed on his wiki, and said many bloggers had confused it with writing poor code on purpose and cleaning it up later. He said he never supported writing code poorly. He supported code that matches your current understanding of the problem, even a partial one, refactored as that understanding grows. The repayment is the refactoring.
So borrowing can be the right call. Shipping early to learn what customers do is a good reason; so is a real deadline, such as a launch tied to an event or a regulator's date. Martin Fowler's technical debt quadrant (2009) separates deliberate debt from inadvertent debt, and prudent from reckless. His point about the prudent, inadvertent kind is the reassuring one: even the best teams often learn the better design only by building the system. Debt is normal. Never repaying it is the problem. Borrowing to ship a feature nobody then uses is the worst loan of all, because you keep paying interest on something that earns nothing.
Principal and interest, counted in days
Two terms carry the whole conversation. The principal is the clean-up: the work needed to bring one part of the system to where it should be. The interest is the extra time every change costs while the debt stays.
Fowler gives the arithmetic in his write-up of the metaphor. A feature that would take four days in clean code takes six in the messy version, so the interest on that change is two days. Removing the mess would take five. For one feature, paying five to save two is a bad deal. If two more changes like it are coming, the clean-up pays for itself.
That is a calculation a product owner can check, argue with and approve. "The code is messy" is not. Debt also explains why small changes stop being small: in a codebase carrying it, every request has a wider ripple, and the ripple is where the interest gets paid.
Explain it in the currency the business pays
The people who pay the interest rarely see the code. They see time per change, incidents, and how long a new engineer takes to become useful. Translate each complaint into one of those.
| What the team says | What the business hears | Say it as interest |
|---|---|---|
| "The pricing module is a mess." | A complaint about taste | "Every pricing change costs about three extra days, and we make one a month." |
| "We need a refactoring sprint." | Two weeks with no features | "Eight days of clean-up saves about two days on each of the next six pricing changes." |
| "The tests are flaky." | An engineering problem | "One release in four slips a day while we rerun the tests." |
| "Onboarding is hard." | A hiring problem | "A new engineer needs three weeks before their first billing change ships." |
Source: invented for this example.
None of the right-hand sentences mentions code quality. Each carries a number the business already cares about, and each can be measured again after the repayment. That second measurement is what keeps the next request for clean-up time credible.
Repay where the interest is highest
The instinct is to clean up the oldest, ugliest code first. Fowler's write-up makes the opposite case, and shows where the metaphor breaks: a bank charges interest as time passes, but code charges it only when you work in that part of it. Messy code that is stable can be left alone. The ugliest file in your repository may be the cheapest debt you have, if nobody has opened it in two years.
Version control already knows where you pay. This lists the files changed most often in the past year:
git log --since="1 year ago" --format= --name-only | grep . | sort | uniq -c | sort -rn | head -20
Cross that list with the places where changes run late, break in production, or wait for the one person who understands them. The overlap is your high-interest debt. Then:
- Price the interest for the top three areas: the extra days per change, and how many changes the roadmap puts there this year.
- Price the principal as a range, not a single number.
- Repay when the interest on the planned changes exceeds the principal, and make the case in those terms.
- Pay in instalments inside the feature work that touches the area, so each repayment arrives with something the business asked for.
- Record each new loan when you take it: what was borrowed, why, and when it should be repaid.
Some principal comes in one block, such as a platform migration. At Vezeeta I migrated core production services from legacy .NET to .NET Core. A repayment that large competes with features for the same people, so it has to be argued in the same currency: what each change on the old platform costs, and how many more changes are coming.
The product owner who asked why two days became two weeks was asking for a statement of account. Give them one: what was borrowed, what it costs each month, and what it would take to pay it off. Then the decision belongs to the people paying the interest.
Written by Eslam Hamed, a Technical Lead and AI Solutions Architect working on enterprise software delivery, from pre-sale to handoff.