Technical Debt Tracking Register
Four documents and four sheets, including the register column that says what each item is costing you per year in engineering hours.
Free download · No account needed
Every debt register in circulation has the same columns: an ID, a description, a severity from one to five, an estimated effort, an owner, a status. It loses to the roadmap every quarter, and not because the engineers explained it badly. Severity and delivery weeks are not comparable quantities, so there is no honest way to put the register beside the feature list and choose. The column that would make them comparable is the one nobody fills in.
It has been named since 1992. In Ward Cunningham's original report on the debt metaphor, the definition is one sentence: every minute spent on not-quite-right code counts as interest on that debt. Not the cost of the rewrite. The tax on ordinary work while the rewrite has not happened. That is measurable from records you already keep, as the excess hours a module costs per change over the codebase median, times how often it actually changes.
Sedgemoor, the billing platform in the worked example, had 47 items and a severity column. Measured, 16 of them sat in code with no commit in twelve months, two of the team's own top four among them. Four of the ten most expensive modules in the codebase were not in the register at all. Invoice rendering, ranked seventh, cost 614 hours a year, more than the top three combined, because it changes 118 times a year and each change runs 5.2 hours over the median.
What's in the pack
Module Change Profile
Every module in the codebase with its change count, median hours per change, contributor churn and last commit date, whether or not the register mentions it.
Debt Register
Each item carrying a measured interest figure in hours per year, its old severity rank and its new rank, so the disagreement between the two stays visible.
Change Failure Correlation
The join against incidents and reverted changes, ending in one ratio: the change failure rate for code that touches a flagged module against code that does not.
Remediation Plan
The only sheet allowed to hold an estimate, with a recovery fraction beside each one, because a refactor rarely removes all of a module's excess cost.
How Interest Is Measured
The method, written so somebody who was not in the room can reproduce every figure, including what the measurement cannot see and why the incident join sits beside it.
Debt Assessment
The standing position: total interest as a share of team capacity, split by temperature, by evidence and by the mechanism that makes each change expensive.
Prioritisation Rationale
The document that goes into planning, opening with four numbers and containing a section naming the high-severity items that lost their rank once measured.
How to use it
- 1
Open in River, or take it blank
Send the pack twelve months of change history inside River, or download the four documents and four sheets and work through the method without an account.
- 2
Build the change profile first
One baseline figure for the whole codebase, then a change count and a cost per change for every module. Every interest figure is an excess over that baseline.
- 3
Rank everything, not just the register
Sort all modules by measured interest and compare against what somebody wrote down. The gap is usually the most useful output of the first pass.
- 4
Join, then cost, then ask
Attach incidents and reverted changes to each item, set a recovery fraction with the engineer who would do the work, and compute payback in months.
Frequently asked questions
Is this template free?
Yes, and the download needs no account and no card. Edit with AI is the optional half: it reads the change history and incident records you send, builds the module profile, and measures interest on every item. Every other pack sits in the template library.
What format are the downloaded files?
Four documents as Word files and four sheets as CSVs, in one zip. The Module Change Profile and Debt Register arrive with their columns ordered and the Sedgemoor rows in place as worked examples, so the arithmetic is visible before you replace them with your own.
We do not track engineering hours per change. Can we still use it?
Yes. Use elapsed time from first commit to merge on the pull requests touching each module, and label the column so nobody compares the two units. A consistent proxy everybody can see beats a scored guess. The ranking holds because every module is measured the same way.
Our static analysis tool already reports a technical debt figure.
That is a different quantity with a similar name. SonarQube's own definition sums a remediation cost attached to each rule that fired, over a cost to develop one line of code, thirty minutes by default, times the line count. Both terms are constants.
So why does that figure never move anybody?
Because neither term looks at the change history, it cannot fall when a module goes cold. At Sedgemoor, 41 percent of a reported 358 days sat in modules with no commit in twelve months. An accurate estimate of a cleanup nobody needed.
What about debt that is a risk rather than a cost?
An interest figure cannot see a danger that has not yet cost anything, and a rarely changed module handling money will sit near the bottom. That is why the incident join sits beside the interest column rather than replacing it. Make the risk argument separately, on its own terms.
What else belongs alongside this?
The measurements either side of it. Engineering metrics and delivery review covers throughput and change failure across the team, inherited codebase documentation maps a system nobody has context on, and postmortem action follow-through tracks what incidents were supposed to fix. The contributor guide is worth sending to whoever is about to touch one of these modules for the first time.
Put a number on the register that a product manager can argue with
Take the Word documents and CSV sheets blank, or open this exact pack in River and send it twelve months of change history.
Edit with AI