Skip to content
Epic Software Labs
All articles

Risk

Technical debt, explained for founders

What engineers mean by technical debt, how to tell deliberate debt from neglect, and how to decide when paying it down beats shipping features.

9 min readEpic Software Labs

Key takeaways

  • Technical debt is the gap between how your system is built and how it would be built if you started now with what you know. Some of it is a deliberate, sensible trade.
  • The symptom that matters is not messy code — it is estimates getting larger for similar work over time.
  • Deliberate debt taken to hit a date is fine. Debt from neglect compounds, because nobody chose it and nobody is tracking it.
  • Never approve a 'stop features and fix the code' quarter. Pay debt down inside the work that touches it.
  • Ask for a business consequence, not a code quality argument. If nobody can name one, it can wait.

Understanding what is technical debt, in practice: your engineers keep mentioning it, You are not sure whether this is a real problem or professional grumbling, and the conversation tends to end with a request for time you cannot easily justify to a board.

Here is a way to evaluate it.

What the term means

Technical debt is the gap between how your system is built and how it would be built if you started today knowing what you now know.

Some of that gap was created deliberately — a shortcut taken to hit a launch. Some accumulated because the product changed and the code did not follow. Some is just age: libraries move on, approaches improve.

The metaphor is precise, which is why it has survived. You borrowed time in the past. You pay interest on that loan in every subsequent change, and the interest compounds.

The two kinds, and only one is a problem

Martin Fowler's distinction — deliberate versus inadvertent debt — is the most useful thing in this whole topic.

Deliberate debt is a decision. "We will hard-code this for launch and generalise it if customers actually use the feature." That is good engineering. It has been chosen, it is understood, and someone can point at it.

Inadvertent debt is accumulation. Nobody decided; the system drifted. This is the kind that hurts, because there is no record of it, no owner, and no trigger for revisiting it. You find out about it through estimates quietly getting larger.

The signal to watch

You do not need to read code to detect this. Watch estimates over time.

If work that resembles work you did a year ago now takes noticeably longer, that is the interest payment appearing in your roadmap. It is the most reliable signal available to a non-technical founder, and it is measurable from data you already have.

Supporting signals:

  • Engineers visibly reluctant to touch particular areas
  • A rising share of bugs that are regressions — things that used to work
  • Releases becoming less frequent, or more nerve-wracking
  • Onboarding a new engineer taking months rather than weeks
  • The same area appearing in incident after incident

Measuring engineering velocity as the underlying signal

Everything in this piece is really about one measurement, so it is worth naming that measurement directly: engineering velocity — specifically, whether it is holding steady, improving, or declining over time for comparable work.

The trap most founders fall into is trying to measure velocity in absolute terms — story points per sprint, features shipped per quarter — and comparing across teams or across very different kinds of work, which produces numbers that mislead more than they inform, because a quarter spent on infrastructure work looks identical to a quarter of no progress if the only metric is feature count. The useful version of this measurement is relative and specific: the same kind of work, tracked over time, in the same part of the codebase.

Concretely, a simple version any founder can run without engineering tooling: pick three or four representative types of change — "add a new field to an existing form," "integrate a new payment method," "add a filter to a report" — and ask engineering to estimate how long each would take today, then compare that against how long similar work actually took a year ago. A gap that has grown noticeably wider is technical debt showing up as a measurable cost, not a feeling.

This measurement matters more than any structural inspection of the code, because it is the one that translates directly into a business case. "The codebase has some technical debt" persuades nobody. "Comparable feature work has slowed by 40% over the past year, concentrated in the billing module" is a number a board can act on.

A worked refactoring budget

Turning "allocate ten to twenty percent of capacity" into a concrete plan a board can approve, using a real shape of company: a team of eight engineers, roughly 320 engineer-days available per quarter.

Setting the number. Fifteen percent of capacity, in this example, is 48 engineer-days a quarter — call it two engineers' worth of time, spread across the team rather than assigned to two specific people, since debt paydown works best woven into ordinary feature work rather than isolated into a separate workstream.

Where it goes. Not evenly across the codebase — targeted at the areas identified through the velocity measurement above. If billing has slowed by 40% and everything else is stable, the bulk of the 48 days goes to billing specifically, not spread thin across every module in the name of fairness.

What "done" looks like. Not a vague sense of improvement — a re-measurement of the same representative work items used to set the original business case. If the billing-area velocity gap was the trigger, the budget is working if that gap visibly narrows within the quarters it was allocated for.

What happens if it does not work. This is the part boards rarely ask about and should. If fifteen percent of capacity for two quarters does not move the velocity number, that is itself informative — it suggests either the debt is deeper than estimated, or the paydown work is not correctly targeted, and both are worth surfacing rather than quietly continuing the same allocation indefinitely on faith.

This structure — a specific percentage, targeted at a measured problem, checked against the same measurement afterward — is what turns "we need to invest in tech debt" from an annual argument into a normal, budgeted, accountable line item.

How to decide what to fix

Ask for the business consequence. Not the code quality argument — the consequence.

Weak: "The payment module is badly structured and hard to read."

Strong: "Every change to billing takes about three times as long as it should, we have shipped four billing bugs this quarter, and the pricing change you want next month is a two-week job that should be two days."

The second is a business case. You can weigh it against other uses of the same time. The first is an aesthetic preference, and while the engineer is probably right, you have no basis on which to prioritise it.

A good engineer can always make the second argument. If nobody can, it genuinely can wait.

How to pay it down

Do not approve a dedicated quarter. "Stop features and fix the code" is almost always a mistake. It is impossible to justify externally, it expands to fill the time available, and it produces no visible progress for months. It also tends to fix the things engineers find interesting rather than the things costing you money.

Allocate a standing share instead. Ten to twenty percent of capacity, continuously. It compounds in your favour and never requires a special conversation.

Fix what you are already touching. The cheapest time to improve a piece of code is while you are in there for another reason. The context is loaded, the tests are being run anyway, and the benefit is immediate.

Prioritise by change frequency, not by ugliness. The worst code in your system, if nobody ever touches it, is costing you nothing. Mediocre code in the area you modify weekly is costing you constantly. This inverts most engineers' instincts and is nearly always the right call.

What to say in a board meeting

Not "we have technical debt". Try:

"Feature delivery in the billing area has slowed by roughly half over the last year. We are allocating fifteen percent of engineering capacity to address the cause, focused on the areas we change most. We expect delivery speed there to recover over two quarters, and we will report the estimate trend."

That is a measurable commitment with a business justification. It is also, in our experience, the conversation that actually gets approved.

Managing technical debt as an ongoing practice, not a one-time fix

Everything above describes how to identify and budget for a specific debt problem. Managing technical debt well is a continuous practice rather than a series of one-off interventions, and the difference between teams that stay ahead of it and teams that periodically fall behind and scramble is usually a small number of habits, not a fundamentally different approach.

Debt gets written down when it is taken, not discovered later. A team that deliberately hard-codes something to hit a launch date should log that decision somewhere visible — an issue, a comment, a registry — at the moment it is made. This is cheap when done immediately and expensive to reconstruct later, and it is the single practice that most reliably separates deliberate debt, which is manageable, from inadvertent debt, which is not.

The velocity measurement runs continuously, not only when someone raises a concern. Waiting until an engineer complains to check whether delivery has actually slowed means the measurement only happens after the problem is already visible to the people closest to it — running it as a standing quarterly check, even briefly, catches the trend earlier and removes the perception that raising debt is a complaint rather than routine reporting.

The refactoring budget is reviewed and re-targeted, not set once and forgotten. A fifteen percent allocation aimed at billing this quarter should be re-evaluated next quarter based on where the velocity data points, rather than becoming a permanent fixture pointed at whatever area was the problem when the budget was first approved.

New debt is compared against old debt before adding capacity elsewhere. A team that is fixing debt in one area while accumulating new inadvertent debt in another at the same rate is running in place. Making this trade-off visible — usually by tracking whether new features are shipped with tests and documentation at the same standard the paydown work restores elsewhere — keeps the whole system from just relocating the problem.

Where debt has accumulated to the point that incremental paydown genuinely is not enough — the architecture itself no longer fits the business — that is a different and rarer decision, covered in rewrite versus refactor. Most technical debt resolves through the ongoing practice described here; it is worth being clear about the narrow set of cases where it does not.

Where this connects to funding and diligence conversations

Technical debt is not only an internal engineering concern — it is one of the things a prospective investor or acquirer will look for directly, covered from that angle in technical due diligence. A company that can produce the kind of velocity measurement and refactoring budget described in this piece, on request, is demonstrating exactly the kind of operational maturity that a diligence process is designed to surface — and a company that cannot answer "how much has delivery slowed in the area we are most worried about" is signalling the opposite, regardless of how the code itself actually looks.

None of these require sophisticated tooling. They require treating technical debt as a metric to track continuously rather than a crisis to respond to periodically, which is the same shift in framing that turns "the codebase needs work" from an argument into routine, unremarkable operational reporting.

The reframe that makes this easier to manage

Technical debt stops being a source of dread once it is treated the way this piece has framed it throughout: a measurable, budgetable, ordinary cost of running a software business, not a moral failing or a crisis waiting to happen. Companies that manage it well do not have less debt than companies that manage it badly — they have the same amount, tracked, prioritised by actual business consequence, and paid down at a rate matched to how much it is actually costing them. That shift in framing, more than any specific technique in this piece, is what separates founders who dread the conversation from founders who have it routinely and move on.

In one sentence

Technical debt is not a verdict on your codebase — it is a number you can measure, budget for, and manage, provided somebody is actually tracking it.

A practical next step

This week, ask your engineering lead to name the single area of the codebase where a straightforward-sounding change has most recently taken far longer than expected. That answer, on its own, is usually enough to identify where a targeted refactoring budget would have the most immediate effect — start the velocity measurement described in this piece there, rather than trying to assess the whole codebase at once.

The board-level version

If a board asks how engineering leadership thinks about this, the strongest answer is not "we do not have much debt" — that claim is rarely credible and rarely true. The strongest answer names the current measured velocity trend, the specific area receiving attention, and the refactoring budget allocated to it, with a plan to re-measure and report back. That answer signals a team managing a normal cost of doing business competently, which is a considerably more reassuring signal than a claim of having no debt at all.

One more thing worth saying

The goal is not zero debt — no functioning codebase has that. The goal is debt that is known, chosen, and paid down at a rate that matches what it is actually costing the business.

The founders who get this right

The founders who manage this well are not the ones who eliminate technical debt — nobody does. They are the ones who ask for the measurement, fund the budget, and check back on whether it actually moved the number.

Frequently asked questions

What is technical debt in simple terms?

The accumulated cost of decisions that made sense at the time but slow you down now. Shortcuts taken to hit a deadline, structure that fitted the old product but not the current one, libraries that have aged. The metaphor is apt: you borrowed time earlier and you are paying interest on it in every subsequent change.

Is technical debt always bad?

No. Deliberately taking a shortcut to hit a market window is often the correct commercial decision, and refusing to ever take one is its own failure mode. What distinguishes healthy debt from unhealthy is whether it was chosen knowingly, written down, and revisited. Debt nobody decided to take is the dangerous kind, because nobody is tracking the interest.

How do I know if we have too much technical debt?

Look at estimates over time for comparable work. If a change that would have taken three days last year now takes two weeks, that is the interest payment showing up. Other signals: fear of touching certain areas, a rising proportion of bugs that are regressions, and a slowdown in how often you can release.

Should we stop building features to fix technical debt?

Almost never as a dedicated period. A quarter with no user-visible progress is very hard to justify and tends to expand. Better to allocate a standing share of capacity — commonly ten to twenty percent — and to pay down debt in the specific areas you are already touching, where the cost is lowest and the benefit is immediate.

How do I evaluate an engineer's request to refactor something?

Ask for the business consequence. 'This code is ugly' is not one. 'Every change to billing takes three times longer than it should, and we have shipped four billing bugs this quarter' is. If nobody can articulate a cost you recognise, it can wait — and a good engineer will be able to articulate it.

How do you measure engineering velocity without technical tools?

Pick three or four representative types of change your team does regularly, ask for a current estimate on each, and compare against how similar work was estimated or actually took a year or two ago. A widening gap for comparable work is the clearest signal of technical debt's real cost, and it requires no code inspection or specialised tooling — just a consistent basis for comparison over time, tracked by area of the codebase rather than as a single company-wide number.

What percentage of engineering capacity should go to a refactoring budget?

Ten to twenty percent is a common range, allocated as a standing share of ordinary capacity rather than a separate dedicated period. The right number depends on how severe the measured velocity decline is — a team with a stable, only mildly aged codebase might sustain itself on the lower end, while a team seeing serious, measured slowdown in a specific area might justify concentrating closer to twenty percent there specifically, checked against re-measurement after a quarter or two rather than left running indefinitely without review.

References & further reading

  1. [1]
  2. [2]
  3. [3]