Technical Debt Documentation: What to Track
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.
## 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
// 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