Most engineering orgs handle technical debt badly in one of two directions. Either they ignore it entirely — focused on shipping features, accumulating debt invisibly until the system becomes painful to change — or they obsess over it, dedicating 30% of every quarter to "platform improvements" that produce no visible value.
Neither extreme works. Technical debt isn't categorically bad, and paying it down isn't categorically good. The right framework treats debt as a portfolio: some you actively pay down, some you refinance (replace one form of debt with a less expensive form), some you accept as the cost of business velocity.
Here's the framework.
What technical debt actually is
The term "technical debt" gets used for everything from genuine debt to engineering preferences. Useful distinctions:
Genuine technical debt: code, architecture, or infrastructure that was deliberately built faster than ideal, with the understanding that it would need work later to remain maintainable. The shortcut was a conscious tradeoff.
Accumulated complexity: code that wasn't deliberately short-cut but has become hard to maintain over time as the system has grown. Not "debt" in the original sense — more like operating cost.
Engineering preferences: code that engineers find aesthetically displeasing or that uses patterns they don't prefer, but that actually works fine. Not debt; just opinion.
Capability gaps: missing features (better observability, automated testing, deployment automation) that the team should invest in. Often called "tech debt" but really infrastructure investment.
The category matters because each has different mitigation strategies. Lumping them together as "tech debt" leads to confused conversations and poor allocation.
The cost-of-debt analysis
The right question for any debt: what is this costing us right now, and what would paying it down save?
Make the cost concrete:
- Engineering hours per week dealing with this debt.
- Bugs traceable to this complexity.
- Features that get cut because they're hard to build given this debt.
- Hiring difficulty because engineers don't want to work in this code.
- Customer issues related to limitations of the current approach.
A piece of debt costing 10 engineer-hours per week is producing $50k+/year of friction. If paying it down takes 200 hours, the payback is under a year. Worth doing.
A piece of debt costing 1 engineer-hour per month is producing $3k/year of friction. If paying it down takes 200 hours, the payback is 7+ years. Not worth doing — the debt is cheaper than the fix.
Most "should we fix this tech debt?" conversations skip the quantitative step. They become aesthetic debates. The quantitative framing forces decisions that map to business value.
The three debt categories
Once you've quantified, debt falls into three categories with different strategies:
Category 1: Pay-down debt
Debt with high ongoing cost where the fix has acceptable payback (under 18 months). Examples:
- A monolithic test suite that takes 45 minutes to run, slowing every PR. Fix: parallelize, modularize. Payback: months.
- A deployment process requiring manual intervention. Fix: automate. Payback: months.
- A core data model that doesn't support a feature the product team has been blocked on for 6 months. Fix: refactor. Payback: depends on the value of the unblocked feature.
These should be on the roadmap as explicit investments. Often managed via a 10–20% allocation of engineering capacity to "platform improvements" — pay-down work that the team prioritizes alongside product features.
Category 2: Refinance debt
Debt that's painful to live with but expensive to fully fix. The right move: refinance — partial improvement that reduces the ongoing cost without paying the full fix cost.
Examples:
- A legacy auth system that's hard to maintain. Full rewrite is a 6-month project. Refinance option: replace with a third-party auth provider over a 6-week migration. Reduces the maintenance burden without rebuilding from scratch.
- An overly coupled service architecture. Full microservice rewrite is multi-year. Refinance option: extract the 2–3 highest-friction components into separate services over 4 months.
- A slow test suite. Full parallelization is complex. Refinance option: identify the slowest 10% of tests and either fix or remove them.
Refinancing is often the right answer because the full pay-down would consume disproportionate resources. The partial improvement captures 80% of the value at 20% of the cost.
Category 3: Accept debt
Debt with low ongoing cost, or where the fix has unacceptable payback. Accept it.
Examples:
- A legacy module that nobody actively maintains and that works fine. Cost: occasional debugging when it surfaces. Fix: rewrite for $200k. Payback: not in any reasonable horizon. Decision: accept.
- A piece of code that engineers don't like aesthetically but that ships reliably. Cost: zero. Fix: nothing to fix. Decision: accept.
- An old library version that's slightly behind current but stable and patched. Cost: minor. Fix: significant upgrade effort with risk of regression. Decision: accept until forced to upgrade.
The discipline of accepting debt is more important than the discipline of paying it down. Engineering orgs often try to fix everything; the better orgs accept that some debt is permanent and stops being interesting to think about.
The strategic patterns
A few strategic patterns that work well at different stages:
Early stage: accept aggressively
Pre-product-market fit, almost everything is debt by some definition. The product's going to be substantially rewritten within 18 months anyway. Pay down only what's blocking near-term progress; accept the rest.
Growth stage: pay down the breaking points
Once product-market fit is found, identify the parts of the system that are breaking under the new scale. Pay those down deliberately. The systems that aren't breaking can remain imperfect.
Mature stage: refinance the largest costs
By the time the company is mature, the system has accumulated decades of decisions. Most of the debt is too expensive to fully pay down. The right pattern: identify the highest-cost pieces of debt, refinance them strategically, accept the rest.
The political problem with debt
Technical debt is politically charged within engineering orgs because:
- Engineers who built the debt feel defensive about it.
- Engineers who joined later see it as evidence of poor judgment by the original team.
- Engineering leadership is judged on feature delivery, not on debt management.
- Product leadership doesn't see debt as their problem until it blocks features they want.
The political problem leads to two failure modes:
- Debt accumulation: engineering produces features at the expense of debt management; debt grows until the system becomes painful to work in.
- Debt obsession: a new engineering leader joins, sees the accumulated debt, and over-corrects toward platform work at the expense of features.
The fix is explicit allocation between product features and platform/debt work. Most healthy engineering orgs run 15–25% of capacity on platform/debt work, with the percentage rising during growth-driven scaling and falling during product-market fit search.
The signs you have a debt problem
The leading indicators that technical debt is becoming structurally problematic:
- Velocity declining without external explanation. Features taking 2x longer than they should.
- Engineer satisfaction declining. Senior engineers leaving because "this codebase is impossible to work in."
- Incident frequency rising with no clear external trigger.
- Product team frustration with "engineering can't ship this" responses.
If you see two or more of these, the debt has become structural and a deliberate intervention is needed.
The intervention pattern: dedicate 8–12 weeks of significant engineering capacity (often 30–40%) to debt reduction, then return to normal allocation. This "debt sprint" pattern disrupts feature delivery short-term but resets the structural issues.
What good debt management looks like
In healthy engineering orgs:
- Debt is named and tracked. A backlog of identified debt items with cost estimates.
- Allocation is explicit. 15–25% of capacity goes to platform/debt work.
- Decisions are quantitative. "This debt costs us X hours/week" framing rather than aesthetic.
- Trade-offs are visible. "We're accepting this debt because the alternative is delaying [feature]" gets discussed openly.
The pattern isn't perfection. It's deliberate management. The companies that get this right ship product without becoming stuck in debt; the ones that don't either drown in debt or drown in debt-payment work.
Technical debt is a portfolio. Pay down the high-cost, low-payback-time items. Refinance the high-cost, high-fix-cost items. Accept the low-cost items. The framework forces the quantitative conversation that produces good decisions. The alternative — debating debt as aesthetic preference — produces the engineering orgs everyone has worked at and complained about.
For broader engineering strategy, see Choosing Your Tech Stack and Engineering Hiring.



