What is technical debt?

Technical debt describes how a software design or implementation can make future work more expensive or difficult. The metaphor is useful when it connects a concrete choice to a recurring consequence: duplicated permission rules require several edits, for example, or a tightly coupled export process makes every format change risky.

Martin Fowler's explanation distinguishes the extra work caused by a difficult design from the work needed to improve it. The metaphor is not a precise accounting system. A team rarely knows the exact future cost, and a small shortcut may never affect an important change.

A bug, an old dependency, and code you dislike do not automatically belong in the same bucket. A current defect needs a response based on its effect. A security exposure needs appropriate incident or risk handling. A debt record should explain how the implementation creates ongoing difficulty instead of using the label to postpone urgent work.

Recognize debt through a change that became harder

Start with a recent task. Which part required repeated edits, unexplained setup, risky coordination, or a workaround? Write down the evidence another developer could inspect. A link to a change, an incident note, a failing check, or a dated observation is stronger than a general complaint that the codebase is messy.

This guide uses an original fictional reporting SaaS. Its export permission checks exist in three handlers. During one fictional change, a developer updated two handlers and discovered the third in review. The team also recorded time spent tracing the copies. These invented observations illustrate what a register can contain; they are not results from ShowMeYourSaaS.

Keep the observation separate from its interpretation. Three permission handlers are an observable structure. Every future change will take twice as long is a forecast that needs support. Name what is known, what is estimated, and what could make the proposed repair unnecessary.

Three original fictional debt records
ImplementationObserved consequenceNext useful evidence
Permission rules copied across three export handlersOne change missed a handler before review caught itWhich upcoming features touch those rules?
Export formatting mixed with delivery logicA format change required delivery tests and manual tracingCan one boundary be extracted without changing behavior?
Old release flag still selects two supported pathsReviewers checked both paths in a recent changeAre any active jobs or clients still using the old path?

Build a debt register with a decision attached

A useful register is short enough to review and specific enough to act on. Give each item an owner, an observed consequence, the evidence date, a trigger for reconsideration, and a next decision. A long list of untimed cleanup suggestions becomes another backlog that nobody trusts.

The CSV download contains three completed fictional items and blank rows. It separates observed effort from estimated repair effort. For the permission example, the invented record notes forty-five minutes of tracing and twenty-five minutes of duplicated edits in one change. A two-to-four-hour repair estimate belongs in another column and remains uncertain.

Do not multiply seventy observed minutes by every future week and call the result guaranteed savings. The next change may touch a different area, and the repair may reveal extra work. Use a range and a review trigger if a projection genuinely helps the decision; retain the assumptions beside it.

Compare fixing now, reducing incrementally, and waiting

For the fictional export, a new permissions feature is already planned. The team can leave the copies, extract one shared rule before the feature, or rewrite the export subsystem. Those options have different scope and uncertainty. A rewrite does not become justified merely because the current code has a debt label.

A bounded extraction could first add characterization checks for the three handlers, introduce a shared decision function, and move one handler at a time. The acceptance condition is unchanged behavior for the existing cases plus one place to change the shared rule. The team would still need a review of the real permission model.

Waiting can be reasonable when the affected workflow is stable, the consequence is small, and no near-term change touches it. Record when that choice should be revisited. If an upcoming feature repeatedly crosses the same difficult boundary, incremental repair may reduce uncertainty before the feature starts.

A decision comparison, not a financial forecast
OptionWhy consider itWhat to check
Leave the copies for nowNo imminent work touches the ruleOwner and revisit trigger remain visible
Extract the shared ruleThe next approved change needs consistent behaviorEquivalent results in every existing handler
Replace the entire export systemA separate requirement may demand a different architectureEvidence for wider scope, migration, rollback, and maintenance

Prioritize against customer work with explicit reasons

Ask what becomes harder if you wait, which planned work is affected, and how reversible the proposed repair is. A small change on a busy path may be more useful than a broad cleanup in an unused module. A numeric score can organize discussion, but it should not conceal unsupported estimates behind decimals.

Bring the evidence into the product roadmap discussion. Explain the relationship between a repair and an outcome the team already values: safer permission changes, dependable exports, or shorter diagnosis of a recurring failure. Reserve time according to the actual work rather than adopting an arbitrary universal debt percentage.

Customer requests and debt records can inform each other without becoming identical. Use the feedback prioritization guide for the requested outcome, then use the debt record to explain delivery constraints. Both should point to the same decision when a repair is a prerequisite.

Keep AI-assisted changes reviewable

An AI coding tool can help locate repeated patterns or propose an extraction, but generated code can also spread a wrong assumption across several files. Ask for a narrow explanation of current behavior and inspect the evidence before accepting a broad cleanup. Passing a type check alone does not prove that permissions or retries still behave correctly.

Choose checks around the behavior that matters. For the export example, exercise allowed and forbidden requests for each handler, failed delivery, and retry behavior. Preserve a small reviewable diff and make it possible to compare the old and new decisions.

Our existing-codebase workflow covers giving a coding assistant useful context. The debt decision remains yours: what consequence are you addressing, and what observation will establish that the change helped?

Review the result and close the record

After the repair, record what changed and what remains. The shared-rule extraction could remove duplicated policy edits while leaving formatting and delivery coupled. Close the specific item that was resolved, and retain a separate record only if the remaining problem has a concrete consequence.

At the next relevant feature, compare the actual work with the original observation. If tracing still dominates, revise the explanation rather than declaring success because the refactor merged. A debt register becomes useful when it improves decisions, including decisions to stop spending time on an unimportant repair.

The decision worksheet includes evidence, options, estimated effort, acceptance checks, a rollback note, and a follow-up prompt. All example values are fictional. Source and resources checked October 27, 2026.