Technical Debt Register: Manage It, Don't Be Buried By It

Technical Debt Register: Manage It, Don't Be Buried By It
Published

12 Jun 2026

Author
Renji Yonjan

Renji Yonjan

Table of Contents

The velocity that quietly drains away

Halfway through year two of a long-running build, the team's velocity quietly drops. Tickets that used to take a day take three. A bug fix in one module ripples through two others before it can be closed. New engineers take six weeks to become productive instead of two. None of this looks like failure to leadership. It looks like the team is busy and the work has just got harder. In a sense it has — because the codebase is now carrying weight nobody chose to put down.

This is the shape of technical debt that nobody tracked. It doesn't trigger an incident, so it doesn't show up in incident reports. It doesn't break the build, so it doesn't show up in CI. It shows up in velocity charts that trend down over quarters, in onboarding times that creep up, and in the slow accumulation of areas of the codebase that engineers route around because nobody wants to be the one to break them. By the time it becomes a board-level conversation, the gap between current capability and required capability is too wide for an afternoon's refactor.

The discipline that prevents this isn't refusing to take shortcuts. Shortcuts are sometimes the right call. The discipline is documenting every shortcut at the moment you take it — what was compromised, why, and what it will cost to fix later. That artefact is a technical debt register, and it sits inside the Right Code pillar of our Built to Last™ 2.0 framework. Tracked debt is a tool. Untracked debt is a tax that compounds, and like any compounding tax, you don't feel it on day one. You feel it on month eighteen.

This guide is for engineers, engineering leads, and CTOs who suspect their codebase is carrying more weight than the team is willing to admit. The register treats technical debt management the way a finance team treats a loan book: visible, priced, prioritised, and paid down on a schedule. That posture is what separates a codebase that lasts past the eighteen-month mark from one that doesn't.

What it costs to leave debt invisible

Technical debt isn't a moral failing. Most of it is the residue of decisions that were correct at the time. The first version of a feature ships with a hard-coded value because the abstraction wasn't clear yet. A third-party integration is wrapped in a thin adapter because nobody knew which provider would survive the next year. A query is left unindexed because the table has fifty rows. These aren't mistakes when they're made. They become mistakes when they're forgotten.

The mechanism by which forgotten debt compounds is mostly invisible until it isn't. An engineer takes a shortcut. The reasoning lives in their head. Six months later, that engineer is on a different sprint or has left. A new feature touches the same area. The new engineer doesn't see the shortcut, so they either work against it (doubling the implicit cost) or build on top of it (doubling the eventual fix cost). After three or four of these layers, the area is effectively quarantined. The team avoids it the way drivers avoid a broken intersection, and every refactoring conversation that could have closed it out gets deferred.

Industry research backs the pattern out. The annual Stack Overflow Developer Survey consistently surfaces technical debt as one of the most cited frustrations in working developers' day-to-day, and the maintainability of software is formalised as a measurable property in standards like ISO/IEC 25010. Neither of those tells you anything you don't already know in your gut. What they do tell you is that the problem is industry-wide and structural, not specific to your team. 

The bill arrives in four places at once. Delivery slows because every change costs more than the last. Hiring gets harder because new engineers can't reach productivity in the timeframe leadership promised. Bug rates rise because the team is building on top of foundations they don't fully understand. And trust erodes between engineering and leadership, because leadership can see the velocity chart but cannot see the cause. The team's honest answer — "the codebase is harder to work in than it was a year ago" — sounds, to a non-engineer, like a complaint. With a register, the same answer becomes a number, a list, and a plan.

What a technical debt register actually is

A technical debt register is a single, persistently maintained document that records every deliberate shortcut, known compromise, and identified weakness in the codebase, along with the cost of leaving it unfixed and the cost of fixing it. It is owned by the engineering lead, accessible to product and leadership, and reviewed at a regular cadence — typically at the end of each sprint, with a full pass at each quarterly planning session.

The minimum useful entry has seven fields:

  • A stable ID and the date logged, so the item can be referenced in pull requests and sprint notes
  • Area of the codebase or product affected
  • What was compromised — the concrete decision, not a vague label like "needs cleanup"
  • Why — the reasoning at the time the shortcut was taken
  • Cost of leaving it unfixed — extra time per related change, blast radius if the workaround fails, any contractual or compliance risk
  • Cost of fixing it — estimated honestly in hours and dependencies
  • Priority and proposed payoff trigger ("before we add a second payment provider", "if usage exceeds 10x", "in the Q3 stabilisation sprint")

A healthy register doesn't get bigger over a quarter. It closes roughly as many items as it opens. Entries get closed in three ways: the team pays down the debt deliberately, the affected area is rewritten in service of a feature and the debt disappears as a side effect, or the assumed cost was wrong and the entry is reclassified as not-debt. All three are legitimate outcomes. The illegitimate outcome is the entry that simply ages.

Who's in the room when the register is used? At the entry level, two people: the engineer who took the shortcut and the engineering lead who approves the entry. At the review level, the engineering lead, the product owner, and — quarterly — the CTO or equivalent leadership voice. The product owner's involvement is the lever that turns the register from an internal engineering artefact into a planning input. When product can see what the debt is costing the roadmap, payoff sprints stop being a tax on velocity and start being a feature of the plan.

Register entries don't replace architecture decision records. The two are complementary. An ADR documents an intentional architectural choice. A register entry documents a known compromise, often made under time pressure, that the team wants to revisit. We link entries to the relevant ADRs and decision log items so the full context survives engineer churn.

Failure modes exist even when the register is present. The most common is the register that nobody reviews — entries accumulate, nothing gets closed, and the artefact quietly turns into a graveyard. The second is the vague entry — "refactor authentication module" with no cost, no trigger, and no owner — which cannot be prioritised, so it never gets touched. The third is what we call the hidden register: an engineering-only document that product and leadership never see, so debt never makes it into roadmap conversations.

A concrete example. Imagine a fintech product whose first version processes payments through a single provider. The team writes the integration as a thin wrapper to ship faster. The register entry reads: ID TD-014; logged April 2025; area payments/checkout; compromised — integration is direct to provider X with no provider-agnostic interface; why — shipping a working checkout for the launch window mattered more than future flexibility, second provider not yet selected; cost of leaving — any second provider takes around two sprints to integrate instead of three days, with no fallback if provider X has an outage; cost of fixing — roughly 1.5 sprints to extract the interface including new tests; trigger — pay down before onboarding any second provider, or if provider X uptime drops below SLO. Twelve months later, when the team decides to add a second provider, this entry is the difference between three days of work and three weeks. That is what tracked debt looks like in practice.

How to implement the register this week

You can have a working register in place inside a working day. The structure is simple. The discipline of maintaining it is what takes practice.

Do four things this week. First, agree the template — the seven fields above, or a variant your team prefers — and put it in whatever tool the team already uses. A page in your existing wiki works. A repo-root TECHNICAL_DEBT.md works. A linked database in Notion or Linear works. Avoid creating a new tool just for this; the register fails most often when it lives somewhere the team doesn't visit.

Second, run a backlog scan. Block two hours with the engineering lead and the most senior two or three engineers, and log the ten items everyone in the room already knows about. The known-unknowns are the highest-value entries. Don't aim for completeness on day one; aim for visibility.

Third, agree the cadence and the debt prioritisation rules. End of every sprint, ten minutes in retro: any new entries, any items closed, any items that have changed priority. End of every quarter, thirty minutes with product and leadership: review the register against the roadmap, decide which items get a slot in the next quarter's payoff capacity. 

Fourth, write the rule into your pull request template. A PR that introduces deliberate debt links to the register entry that records it. A PR that closes an entry links it in the description. This is the single mechanism that keeps the register honest, because it forces the register to be touched at the moment the debt is created, not weeks later when nobody remembers the trade-off.

Avoid three traps. Don't make the register a confession booth — entries are trade-off records, not engineer report cards, and the tone has to come from leadership. Don't tie payoff to discretionary "tech debt sprints" without committing capacity in the actual quarter plan; reserved capacity that never materialises trains the team to assume the register is theatre. And don't try to retrofit every legacy compromise in week one. Log new compromises as they happen; backfill old ones during related work. 

If your delivery framework already includes a decision log and a risk register — both standard inside our project delivery framework — the technical debt register slots in beside them. The three together cover decisions made, risks identified, and compromises taken. Each answers a different question. Together they keep month-eighteen conversations productive.

What this looked like for a SaaS we worked with

A mid-sized SaaS company we worked with — engineering team of around twelve, customer base in the thousands, eighteen months into a long-running build — came to us because velocity had dropped to the point that quarterly commitments were missing by half. The team's diagnosis was that the codebase had got harder to work in. Leadership's diagnosis was that the team had got slower. Neither side had numbers, so the conversation was unwinnable.

We spent the first sprint logging the debt the team already knew about. Seventeen entries by the end of the week, concentrated in three areas: a billing module rebuilt twice under time pressure, an integration layer that had grown to wrap four third-party services without a common abstraction, and a permissions model extended five times since the original design. We costed each item: hours to fix, ongoing cost of leaving, blast radius. The total ongoing cost — extra hours per related change, debugged across the previous quarter — explained almost all of the velocity drop. 

The next four quarters were structured around the register. Each quarter committed a reserved slice of capacity — roughly one engineer-week per sprint — to closing the highest-priority entries. By the end of year two, velocity had not just recovered; it was higher than its previous peak, because three of the worst-quarantined areas of the codebase were now navigable by the whole team rather than only the two original authors. 

In the scenario the team had been living before that, velocity drops by around a third over eighteen months and the team has no shared language to explain why. With the register and a quarterly payoff cadence, the same codebase can hold constant velocity past the two-year mark. The difference isn't talent. It's whether the cost was visible early enough for leadership to allocate against it.

When this matters most, and when it can wait

A technical debt register pays for itself in any codebase that needs to stay healthy past the eighteen-month mark. That includes long-running TaaS engagements, ongoing custom software products, mature Agentic AI delivery where prompts, evals and pipelines accumulate their own debt, and infrastructure inside DevOps engagements where a misconfigured pipeline is as expensive as a tangled module. In those contexts the register is non-negotiable. The cost of not having one is the silent velocity drain described above — visible only when it's expensive to reverse. 

The register can wait in three contexts. A pre-product-market-fit prototype where the next pivot may delete most of the code anyway. A short-lived internal tool with a planned end-of-life inside a year. An MVP that is genuinely experimental and where shipping fast to learn is the only commercial priority. Even then, we encourage logging the three or four largest known compromises somewhere, because the prototype that succeeds becomes the production system, and nobody likes inheriting undocumented decisions.

The honest test is this: if the codebase is going to be edited by someone other than the person who wrote it, the register starts paying back. The longer the codebase lives and the more people touch it, the higher the return.

Where to take this next

Create the file today, agree the template, log five entries from memory. The act of writing five down with cost numbers is enough to shift the team's relationship to debt — from "something we should clean up someday" to "a list we own". Add the PR template line this week. Put the first quarterly review on the calendar.

If you want to see how the register fits inside the wider engagement structure, read our overview of how we deliver custom software. If the register is going to live with a long-running squad, our staff augmentation model describes how we keep code health visible inside an embedded engagement.

Frequently Asked Questions

What is technical debt actually, in plain terms?

Technical debt is the cost of choosing the faster option now over the more durable option later. Sometimes the choice is correct — speed-to-market, learning urgency, or genuine uncertainty about which durable option to pick. The debt isn't the shortcut itself; it's the commitment that the shortcut will be revisited. Untracked, that commitment evaporates. Tracked in a register, it becomes a normal item on the team's plan.

How is a technical debt register different from a bug tracker or a backlog?

A bug tracker records things that are demonstrably wrong. A backlog records things you want to build. A technical debt register records things that work but cost you more than they should — and will cost you more next year than they do today. The register's job, as a code quality tracking artefact, is to make compounding cost visible. Bugs and backlog items don't compound in the same way.

Who should own the register, and who should see it?

The engineering lead owns the register. The team contributes entries. Product owners and leadership see it — not just on request, but as a routine input to roadmap planning. Hiding the register from product is the single most reliable way to make it useless, because debt only gets paid down when there is capacity allocated to it, and capacity is allocated by the people who own the roadmap.

When should we pay down debt, and how much capacity should we reserve?

Most teams that successfully manage debt reserve a recurring slice of capacity rather than relying on dedicated tech debt sprints. A common pattern is roughly ten to fifteen per cent of sprint capacity reserved for closing register items, plus opportunistic closure when a feature happens to touch a debt-laden area. Dedicated tech debt sprints can work, but they are easier to defer when commercial pressure rises. Reserved capacity inside every sprint survives that pressure better.

How do we explain technical debt to non-engineers without making it sound like an excuse?

Show the register. Show the cost-of-leaving column. Show the impact in concrete terms — sprints lost to debug time in debt-laden areas, onboarding weeks added per new hire because of undocumented compromises. Debt explained as a list of priced items with payoff triggers reads, to a CFO or a board member, the way any other operational backlog reads. Debt explained without numbers reads, fairly or not, as engineers asking for time off feature work.

Does AI tooling change how we manage technical debt?

It changes the detection side. Modern code analysis and AI-assisted review — central to our AI-native delivery approach — can flag patterns that look like debt, including duplicated logic, unused abstractions, complexity hot-spots and dependency drift. New entries get cheaper to identify. AI doesn't change the prioritisation or the payoff disciplines, which remain a human judgement call. The register is where AI signals get triaged into entries with cost numbers and owners.