Skip to content
← All writing

How to prioritise tech debt against features

· 6 min read · by Tan Gravam

The short answer

Tech debt loses to features because it arrives as a solution with no problem attached: "refactor the billing module" states no outcome and no cost of waiting, so it cannot be compared with anything. Prioritise it by shaping it like any other demand: what is going wrong today, what will be different afterwards, and what delay costs, shown in evidence from your own recent history — incidents traced to it, committed work it made larger, an end-of-support date. Then let it compete for the same per-team capacity as features, case by case. Keep a fixed percentage only for maintenance too small to be worth a decision, held as a named line. Debt that has been shaped can win on its merits; debt that is only a noun loses, and should.

Every engineering manager has sat through the meeting. The feature has a customer's name on it, a revenue line, a date. The debt item says "refactor the billing module". The feature wins, the engineers conclude that leadership does not care about quality, and leadership concludes that engineers always want to rewrite things. Both are wrong. The debt item lost because of how it was written.

Why debt loses the meeting

"Refactor the billing module" is a solution with no problem attached. It says what the team wants to do and nothing about what is going wrong today, what will be different afterwards, or what waiting another quarter costs. Put a feature request in the same form, "build the export thing", and it would lose too. It is a topic wearing the grammar of a request, and a topic cannot be compared with anything.

The word itself does not help. "Debt" was coined as a metaphor to make the cost legible to people who think in money, and it has decayed into a category label, a bucket of things engineers find unpleasant. A bucket has no outcome. Nobody can say when it is paid off, so nobody can say what a quarter spent on it bought.

There is an asymmetry underneath, too. A feature's requester is in the room, arguing. The requester for debt work is usually the team that would do it, which makes the proposal look like self-interest even when it is the most valuable item on the list. The only cure for that is evidence somebody outside the team can check.

Shape it like any other demand

The fix is not a special process for debt. It is the ordinary one, applied without exemption. Shaping a debt item means answering the three questions any demand has to answer.

What is the problem, stated apart from the solution? Not "the module is a mess". Something observable: every change to pricing rules passes through one file that two people understand, and changes there take far longer than comparable changes elsewhere.

What will be true afterwards? An outcome somebody could check: a pricing-rule change is a contained piece of work that any engineer on the team can pick up. If the honest answer is "the code will be nicer", the item is not ready, and it may never be.

What does waiting cost? This is the question debt proposals skip and features never do. Debt has a cost of delay like anything else. It is paid in a different currency: incidents, and capacity quietly added to every piece of work that touches the area.

An illustration, with invented numbers. Before: "Refactor billing module, about three FTE-months." After: "Three of last quarter's five commitments touched pricing rules. The team's own estimate is that each cost about a month more than it would have without the current structure. Two more are planned for next quarter. Three FTE-months now removes that tax from both, and from whatever follows." The second version can still lose. But it loses to something, on the record, for a reason, where the first simply evaporates.

The fixed percentage: what it buys and what it costs

The popular alternative is to stop arguing case by case and reserve a fixed share of capacity for debt. Twenty per cent is the figure usually quoted. I am using it as an example and not as a recommendation.

What a fixed budget buys is real. It ends the quarterly relitigation, it protects maintenance from requester seniority, and it is easy to explain. For the stream of small things, the dependency bump, the flaky test, the noisy alert, it is the right tool, because none of those is worth the cost of a decision.

What it costs is less often said. A budget decides how much and leaves open on what, so it tends to be spent on what is interesting to fix rather than on what is expensive to leave. It has no outcome, so nobody can say at quarter end what it bought. Because it is a pool and not a promise, it is the first thing raided when an urgent ask arrives in week seven. And it puts a ceiling on the argument: a piece of debt that deserves half a team for a quarter cannot be funded out of a fifth.

So I would use both, for different sizes. Keep a small named maintenance line per team, subtracted before the team's capacity line is drawn, for work too small to be worth deciding on. Anything large enough to displace a feature stops being "debt" at that point and becomes a demand. It competes for the same per-team capacity as everything else, by the same rules, which the piece on what goes in the quarter sets out: plan per team, commit to less than fits, and rank by what the organisation is trying to change and not by who asked.

What evidence makes debt win

Evidence from your own recent history beats any general argument about code quality. Four kinds work, roughly in descending order of force.

  • The tax on committed work. Name the demands above the line that this debt makes larger, and by how much in the delivering team's own estimate. Attached to a feature someone already wants, debt stops being a rival to that feature and becomes part of its price.
  • Incidents traced to it. A count from the last two quarters with the incidents named, not an impression that the area is fragile.
  • A date that is not yours. An end-of-support notice, a certificate or contract expiry, a platform deprecation. A trigger with a calendar date is the one argument that needs no translation.
  • Concentration of knowledge. One person can change this safely, and that person's absence stops the team. Say which commitments depend on them.

What does not work: "engineering health", morale, embarrassment about the code, and anything put through a weighted score. A scoring framework ranks an unshaped debt item to two decimal places and leaves it exactly as undecidable as before.

When shaped debt still loses

Sometimes it should. If the area will be retired next year, or nothing planned touches it, the cost of delay is small and the right answer is no. Then say so. Park it with a review date and the condition that would change the answer, such as "revisit when a second commitment touches pricing", or decline it with the reason written down. Debt items are the classic permanent backlog residents, re-read every quarter and never decided, and that costs more attention than either answer would.

Once it is committed, it is a commitment

Debt work that wins gets no softer treatment than a feature. It has one owner by name, a capacity figure the team agreed to, and an outcome to be closed against. That last part is where debt work most often goes unexamined. A refactor that shipped is not the outcome. The outcome was that pricing changes got cheaper, and the next quarter's commitments in that area are the evidence either way. If they did not get cheaper, the honest close says so, and the next debt proposal is argued with better information.

This is also what protects the work mid-quarter. A named commitment with an owner and a stakeholder who was told the cost of delay can only be displaced visibly. A percentage can be displaced by anyone, a little at a time.

Where DeliverySheet sits

DeliverySheet has no scoring formula and no ranked list. Plan shows an AI priority suggestion (high, medium or low, with its reasons) as context, never as a gate, so nothing in it will put the refactor above the feature for you. A piece of debt work enters as a demand like any other: Capture requires a stated need plus either an impact or a trigger, which is the sentence most debt proposals are missing. Decide then offers plan, a time-boxed discovery, park (with a review date, or indefinitely with a reason), or decline with a reason. A committed demand has an owner and capacity estimated per team in FTE-months, so the debt work is sized by the people who would do it.

I'm Tan Gravam. I build DeliverySheet — it takes a vague work request to a clear delivery decision, so the shape, owner, capacity, dependencies and open questions are on the table before anyone commits people or a date.

$189/month per workspace, unlimited members. 7-day free trial — card required, cancel before it ends and you're not charged. I answer the support email myself.

More on deciding what to commit to

Read the overview: How to decide what to commit to →