Skip to content
Aug 14, 2026·8 min read

Technical debt cost belongs in the budget

Calculate technical debt cost from sprint capacity, incident losses, and delayed margin, then give finance a budget case it can challenge.

Technical debt cost belongs in the budget

Technical debt becomes a budget problem when it changes cash, capacity, risk, or a committed date. Until engineering attaches those effects to a period and a decision, the phrase carries no more financial weight than "the code feels old." A CFO cannot fund a metaphor. A CFO can compare a recurring cost with the price and timing of removing it.

I have watched teams lose this argument by presenting dependency age, cyclomatic complexity, ticket counts, or a red architecture diagram. Those facts may diagnose the cause. They do not price the consequence. The useful unit is money per period, with the operational evidence and assumptions visible underneath it.

The model in this article separates three costs that teams often muddle together: interest paid through extra delivery effort, losses caused by incidents, and contribution margin postponed by delay. Add them only after removing overlaps. Keep uncertainty explicit. The result will not look like an audited liability, and it should not pretend to. It will be a decision model that finance can challenge, update, and put beside other uses of capital.

A debt number needs a counterfactual

Technical debt cost is the difference between what the system consumes now and what it would consume after a specific corrective change. That second state is the counterfactual. Without it, a large maintenance bill says nothing about how much is avoidable.

Define the debt item narrowly enough that one owner can describe both states. "The legacy platform" is too broad. "The batch pricing module forces manual regression across 14 tariff variants" is measurable. So is "releases to the claims service require a four hour freeze because rollback cannot restore the old schema." Each statement identifies an affected activity and the mechanism that makes it expensive.

Use a debt register with one row per mechanism, not one row per complaint. A workable row has these fields:

  1. The system boundary and the behavior that creates extra work or exposure.
  2. The present cost driver, its unit, and the evidence source.
  3. The credible replacement state and the cost driver expected there.
  4. The person accountable for updating the estimate.
  5. The earliest decision or delivery date that the debt can change.

The comparison must use the same demand in both states. If the current service handles 80 releases a year, compare it with 80 releases after remediation. Do not make the replacement look cheap by assuming fewer customers, incidents, reports, or regulatory changes. State any expected demand growth separately.

Accounting and management estimates also need different labels. Most technical debt is not a booked liability under financial reporting rules. Calling it one invites an avoidable dispute with the controller. Treat the calculation as a management estimate for capital allocation unless finance determines that a particular expenditure or obligation belongs in the accounts. The estimate can still affect a budget without appearing on the balance sheet.

A good test is whether someone outside engineering can alter an input without accepting the engineering diagnosis. Finance might challenge the loaded labor rate. Sales might challenge the probability of a launch date. Operations might dispute the hours assigned to an outage. If the model exposes those inputs, the discussion becomes useful. If it hides them behind a single "debt score," everyone can reject the total without explaining why.

Define the decision before collecting more data. A request to replace an entire application needs a different evidence standard from a request to spend five days removing a release bottleneck. Record the proposed action, the cash needed, the capacity taken from other work, and the date by which approval matters. Then collect only evidence that could change that choice. Teams often spend a quarter refining a debt inventory while the budget question remains unstated.

Keep sunk cost out of the comparison. The amount spent building and patching the current system may explain why leaders hesitate, but it does not change the future economics. Compare future cash and capacity under each option. Historical spend belongs in the narrative only when it creates a continuing obligation, such as a support contract or a committed data center charge.

Interest is the capacity consumed every sprint

Debt interest is the incremental effort caused by the current design during normal delivery. Measure the extra hours, compute their loaded cost, and allocate them to the sprint or other planning period in which they occur.

Start with repeated activities: analysis, coding, test setup, regression, deployment, data repair, release coordination, and support after release. Compare observed effort with a defensible baseline. The baseline may come from the same team working in a cleaner component, a recent change that bypassed the constraint, or a time study before and after a small repair. Story points are poor currency here because their meaning varies by team and often changes as the team learns.

Use this calculation for each activity:

interest_per_sprint = events_per_sprint
                    * extra_hours_per_event
                    * loaded_cost_per_hour

capacity_interest_rate = extra_hours_per_sprint
                       / available_engineering_hours_per_sprint

Loaded cost should follow the rate finance already uses for planning. It may include salary, employer taxes, benefits, and allocated overhead. Do not quietly substitute a consultancy rate because it makes the total larger. If finance plans with role specific rates, calculate developer, tester, operator, and manager time separately.

Measure waiting as well as labor, but do not price them the same way. Four engineers waiting two hours for a test environment creates eight hours of displaced capacity if they cannot switch effectively. A release sitting in a queue for two days may consume little labor but delay revenue or risk reduction. Put the first effect in interest and the second in delay. Counting both as labor exaggerates the cost.

Collect a small sample before instrumenting everything. Add two fields to ordinary delivery records for several sprints: the debt mechanism encountered and the extra time it caused. Ask for a short note, not forensic precision. Review obvious outliers with the people who did the work. The aim is an estimate that survives questions, not a time tracking regime that costs more than it reveals.

Keep the numerator incremental. A brittle test suite may make regression take 30 hours instead of 12, so the debt interest is 18 hours. The whole 30 hours is maintenance spend, but only 18 belongs to this decision. That distinction prevents the common claim that remediation will make all maintenance disappear.

Report both money and capacity. "$18,400 per sprint" lets finance compare spending. "0.7 engineer equivalents" tells a head of engineering what the debt removes from the roadmap. The two figures come from the same hours, so never add them together.

Interruptions deserve special care because calendar time and effort diverge. A developer who loses 20 minutes to an unreliable build may need another 15 minutes to recover context, but asking people to estimate cognitive recovery invites noisy numbers. Measure elapsed work on comparable tasks first. If the sample shows a repeatable gap that cannot be explained by task size, include it and document the method. Otherwise record the interruption count as supporting evidence and leave the disputed recovery cost out of the total.

Contractor and vendor charges belong in interest when the debt causes them to recur. A specialist retained solely because nobody on staff can modify an old language is an avoidable run cost if the replacement removes that dependency. A general support agreement that remains necessary after remediation is residual cost. Ask procurement for the actual committed and variable portions rather than allocating the full invoice by instinct.

Incident cost includes more than repair time

Incident cost is the expected loss created by the debt mechanism, not the total cost of every incident touching an old system. Link each included event to a causal path and separate realized loss from prospective risk.

For incidents that already happened, reconstruct cost from records the company trusts: incident timelines, on call logs, payroll rates, cloud or vendor invoices, support cases, credits approved by finance, and transaction records. Use these cost buckets only when evidence exists:

  • response and recovery labor;
  • direct infrastructure or supplier charges;
  • customer credits, refunds, penalties, or written off transactions;
  • contribution margin lost on transactions that did not recover;
  • follow up work required to prevent an immediate repeat.

Do not price employee hours twice. If an engineer spends six hours restoring service and those hours already appear in incident response labor, do not also count them as sprint interest. Mark the time against one cost bucket. Likewise, if delayed orders later complete, count the timing effect or any abandonment, not the full face value of every queued order.

Prospective risk uses frequency and impact. A simple annual estimate is enough when the data is thin:

expected_annual_incident_loss = expected_events_per_year
                              * loss_per_event

expected_loss_per_sprint = expected_annual_incident_loss
                         * sprint_days
                         / operating_days_per_year

Use a range for both inputs. The low case can reflect recent routine events. The base case can use the observed run rate with a typical loss. The high case should describe a plausible severe event and its causal assumptions, not an invented catastrophe. If the system has never produced the feared failure, say that. A risk estimate gains credibility when it distinguishes evidence from judgment.

Availability percentages rarely make a good budget input on their own. The same 40 minutes of downtime can stop a revenue channel, delay an internal report, or pass unnoticed during an idle window. Price the business process that failed, at the time it failed. Operations owns duration and recovery facts. Finance or the business owner should own the unit value attached to missed activity.

Security and compliance exposure need the same discipline. Do not multiply an enormous theoretical fine by a guessed probability and call it precision. Identify the control failure, the affected records or process, the remediation work already required, and any contractual consequence that counsel or finance accepts. Keep unpriced exposure in a separate narrative risk field. A blank dollar value is more honest than a number with no defendable inputs.

Near misses can inform frequency without being priced as realized losses. A failed overnight batch caught before settlement may reveal the same defect path as a costly daytime failure, but the company did not incur the customer loss. Count the event when estimating recurrence, then use the impact appropriate to its timing and controls. This avoids the opposite errors of ignoring warnings and pretending every warning was a disaster.

Insurance does not erase incident cost. A policy may reimburse a defined portion after a deductible and investigation, while response labor, customer churn, and timing effects remain. Finance should enter expected recovery as a separate offset only when the policy and event make it credible. Engineering should never subtract a guessed insurance payment from the incident estimate.

Delayed revenue is a timing calculation

Delayed revenue cost is the contribution margin postponed or lost because debt extends the path to a commercial event. Revenue itself is usually the wrong amount: the company avoids some variable costs when a sale does not occur, and some delayed sales arrive later.

Name the event first. It might be general availability of a paid capability, onboarding a contracted customer, entering a region, changing a price, or increasing transaction capacity. Then identify the dependency chain from the debt mechanism to that date. "Old code slows us down" is not enough. "Every product change requires a six day regression cycle on the shared billing rules, and this launch needs three such cycles" can be checked.

Use contribution margin and a time profile:

margin_delayed = expected_revenue_in_period
               * contribution_margin_rate
               * probability_debt_is_on_critical_path

economic_cost_of_delay = margin_lost_permanently
                       + financing_or_opportunity_cost_of_margin_postponed

Keep postponed margin separate from permanently lost margin. If a launch slips one sprint and customers simply start one sprint later, the entire first sprint's margin has not vanished forever. The economic cost is the value of receiving that stream later, plus any customers or contracts that will genuinely be lost. A simple cash flow schedule makes this visible.

Product and sales must supply the commercial inputs. Engineering owns the extra duration and the causal dependency. Finance owns contribution margin and the method used to value timing. That split prevents engineering from inventing an attractive revenue forecast and prevents finance from treating a technical dependency as a generic delivery complaint.

Beware portfolio arithmetic. Five features may all depend on the same database repair, but the company might have capacity to launch only two of them this quarter. Adding the full forecast for all five creates imaginary upside. Model the approved or probability weighted portfolio under the actual delivery constraint.

There is also an option value that should usually remain outside the headline total. A cleaner system can make experiments cheaper and future changes possible, but those opportunities are not committed cash flows. Describe them and track whether they become funded work. Do not use them to rescue a weak remediation case.

Date confidence matters as much as forecast confidence. If product gives a fixed revenue forecast but the launch already has three unresolved dependencies, debt may not determine the actual date. Map the critical path with owners and exit conditions. Set the probability input to the chance that removing this mechanism changes the commercial date, not the chance that engineers finish the repair.

Capacity increases need a different model. If the current system caps orders or accounts, estimate demand above the cap by period and apply contribution margin only to transactions the business can serve after the change. Do not price theoretical headroom as revenue. A system that can process twice as much has no extra economic return when demand remains below the old ceiling.

Ranges are more credible than false precision

Keep regulated code inside
Supplied models can run air-gapped on customer hardware or hardware rented from CodeHero.

A debt estimate should show a low, base, and high case because its inputs mix measurements with forecasts. One exact total, especially one ending in oddly precise dollars, signals that uncertainty has been hidden rather than removed.

For each input, record its source, observation window, owner, and confidence. An export of release timestamps has stronger evidence than a workshop estimate of interruption time. A signed customer order has stronger evidence than an unapproved product idea. This does not mean weak inputs are useless. It means the output must show how much they control the decision.

Run sensitivity analysis by changing one input at a time. If the remediation case works only when a speculative revenue launch is included, say so. If recurring test labor alone repays the change, the decision is less exposed to forecast error. Rank inputs by how much they move net present value or payback, then spend measurement effort on the first few.

Use the company's normal discount rate and investment horizon. Engineering should not invent either. For a recurring sprint cost, the present value calculation can stay simple:

present_value = sum(period_cost[t] / (1 + period_rate)^t)

net_value = present_value_of_avoided_costs
          - remediation_cost
          - transition_cost
          - residual_cost

Residual cost matters. The replacement will still need maintenance, incidents will not fall to zero, and teams will still run tests. Model what remains after the change. Also include transition cost: dual running, migration support, training, data reconciliation, and temporary delivery slowdown. Omitting those items makes an otherwise sound case look promotional.

Set an expiry date on the estimate. Rates, incident frequency, roadmap dependencies, and system demand all change. Refresh frequently measured interest each planning cycle, and revisit large incident or revenue assumptions when their evidence changes. An old estimate should not become permanent truth because it once appeared in a board deck.

Correlated risks need one more check. A release freeze may increase delivery labor and make a launch slip, while the same underlying schema change also raises incident probability. Those effects can coexist, but their high cases may depend on the same rare event. Do not combine every worst case as if all of them occur independently. Present a coherent scenario that states which events happen together, then compare it with the base case.

Round outputs to the precision of the evidence. If extra effort came from interviews and a short sample, reporting $417,263 implies knowledge the team does not have. Use a sensible rounded amount and keep the underlying calculation available. Precision in the formula is useful; precision in the displayed answer must be earned.

A worked example exposes the assumptions

Keep behavior in the evidence
A parity harness checks the rewritten system against your recorded production traffic.

Consider a billing service whose shared rules require a manual regression run for every release. The example uses invented round numbers to demonstrate the method, not to claim a typical result.

The team ships four times per two week sprint. Each release consumes 22 extra hours across engineering, testing, and release coordination compared with changes in a newer isolated service. Finance uses a blended loaded rate of $125 per hour. The system also caused three attributable incidents in the previous year, with documented labor, credits, and lost margin averaging $24,000 per event. A planned pricing capability depends on the same rules, and the approved forecast shows $160,000 of monthly revenue at a 65 percent contribution margin. Product believes the debt has a 50 percent chance of adding one sprint to launch.

Put the inputs into a worksheet that can be reviewed line by line:

cost_bucket,input,base_value,source,owner
interest,releases_per_sprint,4,release_log,engineering
interest,extra_hours_per_release,22,time_sample,engineering
interest,loaded_cost_per_hour,125,planning_rate,finance
incident,events_per_year,3,incident_review,operations
incident,loss_per_event,24000,ledger_and_timeline,finance
delay,monthly_revenue,160000,approved_forecast,product
delay,contribution_margin_rate,0.65,margin_model,finance
delay,probability_on_critical_path,0.50,dependency_review,product

Interest is 4 x 22 x $125, or $11,000 per sprint. With 26 two week sprints as a planning convention, expected incident loss is about $2,769 per sprint. The one sprint delay places roughly half a month's contribution margin at risk before probability weighting: $160,000 x 0.65 x 0.5 x 0.5, or $26,000. The timing factor is one half because a two week sprint is roughly half of the monthly forecast period.

Do not immediately add $26,000 to every sprint. It is a one time, decision linked exposure for the launch window. The recurring run rate is $13,769 per sprint from interest and expected incidents. The decision view should therefore show two lines: recurring avoidable cost and event based delay exposure.

Suppose remediation costs $310,000, transition costs $45,000, and the corrected service retains 25 percent of current interest and incident loss. Avoided recurring cost is then about $10,327 per sprint. Simple undiscounted payback on the $355,000 implementation and transition total is about 34 sprints without the launch effect, or about 32 sprints if the probability weighted delay is avoided. Finance can apply its normal discount rate and horizon from there.

That may be an unattractive payback. The model has still done its job. The company can defer the work, narrow its scope, look for a cheaper intervention, or accept the cost knowingly. Engineering should not inflate the incident scenario until the answer changes.

Now test the strongest assumptions. If the extra release effort is 14 hours rather than 22, avoided recurring cost falls. If only one incident was truly caused by the rules module, it falls again. If the pricing work leaves the approved roadmap, delete the delay line. A case that remains positive after those edits deserves priority. A case that collapses has identified exactly which evidence the team needs next.

The budget line needs an owner and a cadence

The useful operating artifact is a debt cost ledger tied to planning, not a presentation assembled once for annual budgeting. Engineering updates activity volumes and extra effort. Operations updates incidents. Product updates critical path dates. Finance controls labor rates, margins, discounting, and the definition of recognized loss.

Give each debt item four numbers on the planning sheet: current recurring cost per sprint, event based exposure, remediation and transition cost, and expected residual cost. Keep the low, base, and high cases available underneath. The approved budget line can use the base case, while the range shows the decision's exposure.

The review cadence should follow how quickly inputs change. A high volume delivery constraint may need a sprint review. Incident estimates may change after each attributable event. Revenue delay should change only when an approved forecast or dependency changes. Recalculating every field every two weeks creates busywork and teaches owners to ignore the ledger.

Use stable identifiers so costs do not migrate between labels. If the same schema constraint causes release labor and an outage, both entries should point to one debt item with separate cost buckets. When remediation ships, leave the row open long enough to compare predicted residual cost with observed results. That post change check calibrates future estimates and catches work that moved elsewhere.

Budget requests should present choices. Option A may tolerate the debt and fund its recurring cost. Option B may contain it with a smaller repair. Option C may replace the affected component. Show cost, timing, residual exposure, and confidence for each. A single take it or leave it rewrite proposal invites finance to debate the ambition instead of the economics.

Do not turn the ledger into an engineer performance measure. Teams inherit constraints and make rational local tradeoffs under deadlines. If leaders use reported debt cost to punish a team, the data will become mysteriously clean. Use it to choose investments and verify outcomes.

Replacement economics must include behavior parity

Modernize mixed legacy estates
COBOL, JCL, RPG, CL, VB6, Delphi, and web monoliths can enter one rewrite scope.

A legacy rewrite earns its budget only when the avoided cost survives delivery risk. The replacement estimate must include discovering undocumented behavior, proving business parity, migrating data and traffic, operating both versions during transition, and retiring the old path. A cheap code conversion that omits those activities has not priced the project.

Transliteration also weakens the economic case. Reproducing obsolete module boundaries in a new language preserves much of the coordination cost that created the interest. The target design should remove the measured mechanism: isolate the billing rules, make rollback independent of schema restoration, or replace manual regression with executable behavior checks. Tie each design change to a row in the cost ledger.

Parity evidence should use real behavior where possible. Recorded production requests and outputs, sanitized under the company's controls, can form a comparison harness. Add boundary cases from incident records and business rules that traffic rarely exercises. Define acceptable differences before running the comparison, since timestamps, generated identifiers, ordering, and floating point behavior can differ without changing the business result.

CodeHero uses this approach when it rewrites legacy systems into Go, Rust, and TypeScript: its platform reads the whole codebase and checks behavior with a parity harness against recorded production traffic. Projects are delivered in under 30 days, so the quote can be compared with the recurring sprint cost and event exposure without pretending the transition lasts an indefinite period.

The approval memo should state what happens if the replacement misses its cost target or parity gate. A staged cutover, an explicit rollback point, and ownership of residual defects belong in the transition cost. So does the temporary capacity taken from feature work. Put those facts in the estimate before approval, not in the incident review after launch.

Once the new path runs, measure the same inputs used to justify it. Release effort, incident frequency, recovery labor, and critical path duration should fall by the amounts the budget assumed. If they do not, keep the ledger open and find where the cost moved. A debt number is credible when it can prove itself wrong.

FAQ

How do you calculate the cost of technical debt?

Calculate incremental delivery labor, expected incident loss, and the economic cost of delayed margin separately. Compare each current cost with a defined post-remediation state, remove overlaps, and show low, base, and high cases.

What counts as interest on technical debt?

Interest is the extra capacity the current design consumes during ordinary work. Count incremental analysis, testing, deployment, coordination, and repair time, but exclude effort the replacement would still require.

Should technical debt appear as a financial liability?

Usually, the decision model belongs in management reporting rather than on the balance sheet. Finance should decide the accounting treatment of any specific obligation or expenditure; engineering should not label an estimate as a booked liability.

How do you put incident risk into a budget?

Tie past incidents to the debt mechanism, reconstruct documented loss, and estimate future frequency and impact as ranges. Keep speculative exposure outside the dollar total when nobody can defend its inputs.

Is delayed revenue the same as lost revenue?

No. Delayed revenue may arrive later, while lost revenue never arrives. Price postponed contribution margin using the company's timing method, then add only the portion likely to disappear permanently.

Can story points measure technical debt cost?

Story points can help a team plan, but they are unstable financial units and cannot be compared reliably across teams. Convert observed incremental work into hours, then apply finance-approved loaded rates.

How often should a technical debt estimate be updated?

Update each input when its evidence changes. High volume sprint interest may need frequent review, while commercial delay should change only when an approved forecast or dependency changes.

How do you avoid double counting technical debt?

Assign every hour and loss to one cost bucket and one debt mechanism. Separate recurring interest from event exposure, and do not count delayed transactions as lost if they later complete.

What if the remediation case has a long payback?

Show the result without inflating risk. The company can accept the recurring cost, narrow the repair, seek a cheaper intervention, or wait until demand changes the economics.

How do you prove a legacy rewrite paid off?

Measure the same inputs before and after cutover: extra release effort, attributable incidents, recovery cost, and critical path delay. Keep the ledger open until observed residual cost can be compared with the approved estimate.