codeintelligently
Back to posts
Technical Debt Intelligence

Technical Debt Documentation: What to Track

Vaibhav Verma
8 min read
technical-debtdocumentationengineering-managementtemplatesprocess

Technical Debt Documentation: What to Track

For 2 years, my team tracked technical debt in Jira. We created 183 tickets tagged "tech-debt." We completed 29 of them. The rest sat in the backlog, growing stale, duplicating each other, and providing zero useful signal about what was actually hurting us.

Then I replaced all 183 tickets with a single living document: a Technical Debt Register. It had 14 entries. Each entry had business context, cost data, and a remediation trigger. Within one quarter, we'd resolved 6 of them and could demonstrate $180K in annualized savings.

The difference wasn't that we suddenly cared more about debt. It was that we finally documented it in a way that made action possible.

Why Tickets Don't Work for Debt Tracking

Technical debt isn't a task. It's a condition. Putting it in Jira alongside feature work is like putting "high blood pressure" on your grocery list next to "buy milk." It's a fundamentally different category that requires a fundamentally different tracking mechanism.

Tickets fail for three specific reasons:

1. No business context. A Jira ticket says "Refactor payment validation." It doesn't say "This module adds 12 hours to every payment feature and caused 3 incidents last quarter." Without business context, debt tickets can't compete with feature tickets that have clear customer value.

2. No decay tracking. Debt gets worse over time. A ticket created 6 months ago might describe a problem that's now 3x worse, or might describe a problem that resolved itself when the team migrated to a new service. Tickets are snapshots. Debt is a trend.

3. No connection between items. Five separate "refactor payments" tickets might all stem from the same architectural problem. Tickets treat symptoms individually. A debt register treats root causes.

The Technical Debt Register

Here's the template I use. Every entry has 6 sections. No more, no less.

markdown
## DEBT-[NUMBER]: [Descriptive Name]

### Summary
[2-3 sentences: What is the debt, where does it live, why does it exist]

### Business Impact (Updated Quarterly)
- Delivery overhead: [X hours per feature touching this area]
- Incident contribution: [X incidents in last 90 days]
- Teams affected: [which teams]
- Estimated annual cost: [$X]

### Root Cause
[Why does this debt exist? Was it a deliberate trade-off? Did context change?
What decision led here?]

### Remediation Plan
- Approach: [Brief description]
- Estimated effort: [person-weeks]
- Dependencies: [what needs to happen first]
- Risk: [what could go wrong with the fix]

### Remediation Trigger
[Specific, measurable condition that makes fixing this urgent]
Example: "When monthly incidents in this module exceed 5" or
"When the next feature requires changes to this area"

### Status & History
- [Date]: Created. Estimated cost: $X/year
- [Date]: Quarterly review. Cost updated to $Y/year. Not yet triggered.
- [Date]: Trigger condition met. Remediation scheduled for Sprint 14.
- [Date]: Resolved. Post-fix cost: $0. Confirmed by [metric].

The remediation trigger is the most important field. Without it, every debt item gets the same treatment: "we should fix this someday." With a trigger, you have a clear decision point. Either the condition is met and you act, or it isn't and you wait.

What to Track: The 4 Categories

Not all debt deserves a register entry. I classify debt into 4 categories and only formally track the top two.

Category 1: Architecture Debt (ALWAYS TRACK)

Structural decisions that constrain how the system can evolve. These are expensive to fix but get more expensive every month you wait.

Examples:

  • Monolith that needs to be decomposed
  • Shared database coupling services together
  • Authentication system that can't support new requirements
  • Synchronous processing that needs to be async
typescript
// Example register entry for architecture debt
const architectureDebtExample = {
  id: "DEBT-007",
  name: "Synchronous order processing pipeline",
  summary: `Orders are processed synchronously through a chain of 6 service
    calls. Any failure in the chain requires manual intervention. The pipeline
    can't scale beyond 50 orders/second.`,
  deliveryOverhead: "8 hours per feature touching order flow",
  incidents: "4 in last 90 days (timeouts, partial failures)",
  annualCost: 142000,
  trigger: "Order volume exceeds 35/second (currently at 28, growing 15%/month)",
  estimatedEffort: "6 person-weeks",
};

Category 2: Dependency Debt (ALWAYS TRACK)

Third-party libraries, frameworks, or services that are outdated, deprecated, or approaching end-of-life.

DEPENDENCY DEBT REGISTER

| Dependency     | Current | Latest | Gap    | Risk Level | Trigger          |
|----------------|---------|--------|--------|------------|------------------|
| Node.js        | 18.x    | 22.x   | 4 major| HIGH       | EOL date: Apr 26 |
| Express        | 4.18    | 5.1    | 1 major| MEDIUM     | Security advisory |
| TypeORM        | 0.3.x   | 1.0    | 1 major| HIGH       | Blocks Node 22   |
| React          | 18.2    | 19.1   | 1 major| LOW        | Next feature need |
| PostgreSQL     | 14      | 17     | 3 major| MEDIUM     | EOL date: Nov 26 |

Track the gap, the risk level, and the trigger. Don't upgrade everything preemptively. Upgrade when there's a reason: security vulnerability, EOL date, or it blocks something you need.

Category 3: Code Quality Debt (TRACK SELECTIVELY)

Messy code, missing tests, inconsistent patterns. Only track items that show up in your hotspot analysis (high churn + high complexity) or that cause incidents.

Don't create a register entry for "this file is ugly." Create a register entry for "this file has been modified 34 times in 6 months and caused 2 production incidents because the error handling is inconsistent."

Category 4: Process Debt (DON'T FORMALLY TRACK)

Slow CI, manual deployment steps, missing documentation. Fix these as part of normal development. They don't need a formal register entry because they're usually quick wins that should just be done.

The Contrarian Take

Most debt documentation advice tells you to be thorough. Track everything. Create detailed records. I disagree. Over-documentation is itself a form of waste.

I've seen teams spend more time maintaining their debt register than fixing debt. 50 items in a register is not better than 12. It's worse, because the signal gets lost in the noise. Nobody reads a 50-item register. Everyone reads a 12-item register.

Here's my rule: if your debt register has more than 20 items, you're tracking too much. Merge related items. Delete items that haven't been reviewed in 2 quarters. Keep only the debt that has a realistic remediation trigger and a quantifiable business impact.

A lean register that drives action beats a thorough register that drives nothing.

The Quarterly Review Process

The register only works if you review it. Here's my process:

Monthly (30 minutes, engineering leads only):

  • Update business impact numbers for top 5 items
  • Check triggers: has any condition been met?
  • Add any new items from incidents or team feedback
  • Remove any items that are no longer relevant

Quarterly (1 hour, engineering + product leadership):

  • Present the full register with updated costs
  • Review trends: is total debt cost going up or down?
  • Decide on Q+1 remediation investments
  • Align debt work with product roadmap

The Quarterly Report Template:

TECHNICAL DEBT QUARTERLY REPORT - Q1 2026
==========================================

REGISTER SUMMARY
  Active items: 14 (was 16 last quarter)
  Items resolved: 5
  Items added: 3
  Net trend: IMPROVING

COST SUMMARY
  Total estimated annual debt cost: $820K (was $940K)
  Reduction this quarter: $120K
  Investment this quarter: $45K (2 engineers, 3 weeks)
  ROI: 2.7x

TOP 3 ITEMS BY COST
  1. DEBT-007: Sync order pipeline ($142K/yr) - TRIGGER MET
  2. DEBT-003: Legacy auth module ($98K/yr) - monitoring
  3. DEBT-011: Test coverage gaps in billing ($87K/yr) - planned Q2

RECOMMENDATION
  Invest 2 engineers for 4 weeks in Q2 to address DEBT-007.
  Projected savings: $110K/year. Payback: 5 months.

Tools for Managing the Register

Keep it simple. I've tried dedicated tools and always come back to basics:

Google Docs or Notion: For the register itself. Living document, easy to update, easy to share with non-engineers. Version history built in.

Spreadsheet: For the dependency debt table and cost calculations. Formulas make quarterly updates fast.

Your existing project tracker: For the actual remediation work once a trigger is met. Now it's a project, not theoretical debt, and it belongs in your sprint planning tool.

Don't buy a specialized debt tracking tool until your register process is running smoothly with simple tools. The process matters more than the tool. Every time.

$ ls ./related

Explore by topic