Modernization & Cloud

The Cost of Technical Debt: What It Actually Costs You

10 min read

Technical debt costs you developer time before it costs you anything else, and the bill is bigger than most budgets admit. McKinsey surveyed CIOs and found they peg tech debt at 20 to 40 percent of their entire technology estate’s value before depreciation. Stripe measured developers spending about 42 percent of the work week on maintenance and bad code instead of new work. Put a dollar figure on that and it gets real fast: a 10-developer team paying a 20 percent debt tax burns roughly $340K a year in salary just servicing the debt. That’s the number this post helps you calculate, and then decide what to do about.

We’re gmware, a custom software development firm in Austin, TX with engineering centers in Bangalore and Mohali, India, and we get called in when a team’s velocity has quietly cratered and nobody can say why. This is how we price technical debt for a CFO, and how we decide what’s worth paying down versus leaving ugly forever.

What technical debt actually costs, in dollars

The cleanest way to price debt is the developer-time tax. You lose a fraction of every engineer’s capacity to working around bad code, and that fraction has a fully-loaded salary attached to it. Stripe’s developer research put the maintenance-and-bad-code share at about 42 percent of the week, of which a large chunk is debt specifically rather than healthy upkeep.

So run the math on your own team. Take your fully-loaded cost per developer (salary, benefits, overhead, not just base pay), multiply by the share of time lost to debt, multiply by headcount. Here’s a 10-person team at a fully-loaded $170K per engineer, across three honest scenarios.

Debt tax on capacityAnnual cost, 10-dev teamWhat it feels like
10% (light)~$170K/yearA tidy codebase with a few rough corners
20% (typical)~$340K/yearEvery feature takes longer than the estimate
30% (heavy)~$510K/yearYou’ve stopped promising dates because you can’t hit them

That $340K in the middle row isn’t a soft cost. It’s a full engineer and a half, salaried, producing nothing but workarounds. And it’s the part you can measure. The velocity, reliability, and security drag underneath it is harder to price and usually larger.

Why the drag costs more than the wasted hours

The salary tax is the floor. The bigger cost is what debt does to everything downstream. Every change to a tangled system takes longer, ships with more risk, and needs more testing. That’s the “interest” in the debt metaphor, and it’s charged on every future commit, not once.

Reliability is where it surfaces to the customer. CISQ estimated poor software quality cost the US economy about $2.41 trillion in 2022, with accumulated technical debt at roughly $1.52 trillion of that. That’s not an abstract macro figure. It’s outages, failed deployments, and bug-fix cycles that could have gone to product, summed across the economy.

Then there’s morale, which a CFO shouldn’t dismiss because it turns into attrition. Stack Overflow’s 2024 survey found 62.4 percent of professional developers name technical debt their single biggest frustration at work, ahead of every other complaint. Good engineers leave teams where the work is fighting the codebase. Replacing a senior developer costs a lot more than the refactor would have.

Not all technical debt is worth fixing

Here’s an opinion we’ll defend: most technical debt should never be paid down. Some code is fine being ugly forever.

A messy internal script that runs once a month, that nobody edits, that fails loudly and harmlessly if it breaks, costs you nothing to leave alone. Refactoring it is pure waste. The debt metaphor gets abused here, because people treat every bit of ugly code as a liability with a due date. It isn’t. Debt only costs you when you keep paying interest on it, and you only pay interest on code you actually touch.

The two things that decide whether debt is expensive:

  • Interest rate: how often you edit this code. High-churn files charge you the tax on every change. Frozen code charges you nothing.
  • Blast radius: what breaks if it fails. Your payments path failing is a very different day than a logging helper failing.

Debt that’s low on both axes is not a problem to solve. It’s a decision to make on purpose, and the decision is usually “leave it.”

A prioritization matrix for what to pay down

Score each chunk of debt on those two axes and it sorts itself. This is the matrix we use to decide what gets a refactor and what gets ignored.

Low blast radiusHigh blast radius
High interest (edited often)Schedule: fix while you’re in there anywayFix now: this is where debt compounds fastest
Low interest (rarely touched)Leave it: ugly forever is fineWatch it: harden or wrap, don’t rewrite yet

The top-right quadrant, high-interest and high-blast-radius, is the only debt that’s clearly worth stopping to fix. It’s the code you change constantly that also hurts badly when it breaks. Everything else is a scheduling call or a deliberate “no.”

If the top-right quadrant of your codebase is a whole aging platform rather than a few files, you’re past refactoring and into a modernization decision. We break down what that runs in our guide to legacy application modernization cost. And if the debt is a framework version quietly falling out of support, that’s a hard deadline, not a preference, which is exactly the situation we cover in the .NET 8/9 end-of-support upgrade plan.

How to decide: pay down, tolerate, or replace

Once debt is scored, the action is usually one of three, and the right one depends on how much of the system is affected.

A quick word on debt from AI-generated code, because it’s a new flavor of the same problem. Code that a model wrote fast and nobody reviewed carefully lands squarely in the high-interest quadrant the moment you start editing it, and it hides its debt well. If that’s your situation, we wrote a whole piece on cleaning up and rescuing an AI-generated codebase.

How technical debt turns into a security cost

Here’s the one debt category where “leave it ugly forever” is the wrong call, and we’ll defend that. Everywhere else, ugly-but-stable code that nobody touches is fine to ignore. Security debt isn’t like that. It doesn’t sit still. Unpatched, tangled, out-of-support code ages into CVEs and audit findings on its own schedule, not yours.

Start with the dependency clock. Every framework and runtime you depend on has an end-of-support date, and after that date the vendor stops shipping security patches. That turns a “we’ll get to it” item into a hard deadline. When .NET 8 and .NET 9 both stop getting patches on the same day, every new vulnerability in that runtime stays open in your stack from then on. We wrote the whole playbook for that specific cliff in our .NET 8 and 9 upgrade plan, and the shape repeats for every framework, database, and OS you run. The date is set by someone else. Your only choice is whether you move before it or after.

Then there’s the tangle. This is the part teams underrate. When code is a knot of hidden dependencies and no tests, a security patch stops being a one-line bump. You can’t tell what a change will break, so the safe patch gets delayed, scheduled for “next quarter,” or quietly skipped. The debt you took on for speed two years ago is now the reason you can’t ship a fix fast when a real vulnerability drops. Interest and blast radius compound at the same time.

That’s the tie-back to the matrix earlier in this post. We rank debt on two axes: how much interest it charges you (how often you touch that code) and how big the blast radius is if it fails. Most low-interest, low-blast-radius debt lands in the “harden and watch” box: leave it, monitor it, don’t spend on it. Security debt breaks that rule. An internet-facing, out-of-support component is high-blast-radius by definition, no matter how rarely you touch it. A component you haven’t opened in three years still answers requests from the entire internet. “Harden and watch” is not enough there. Out-of-support internet-facing code jumps straight to the top-right quadrant, the fix-now box, and stays there until you patch or retire it.

So when you take our matrix to your own estate, apply one override before anything else. Any component that’s both reachable from the internet and past its support window comes out of “harden and watch” and goes to the front of the line. It doesn’t matter that the code is stable or that nobody’s edited it since the last CEO. Stable and exposed and unpatchable is exactly the profile attackers scan for. This is the debt you pay down on a deadline, and the deadline is usually already on the calendar.

How gmware prices and pays down technical debt

We start with a read, not a rewrite quote. We measure where your engineering time is actually going, map the debt onto the interest-versus-blast-radius grid, and tell you which quadrant each system sits in. Most of what we find, we tell you to leave alone. That’s not us turning down work; it’s the honest answer, and refactoring stable code you never touch is money lit on fire.

For the debt that’s genuinely expensive, our legacy application modernization practice runs the fix from Austin with engineering in Bangalore and Mohali, so you get senior oversight on US hours without US-only burn rates. When the debt is really a strategy problem, an aging platform holding back everything you want to build next, that’s a digital transformation conversation, and it starts with the same honest read of what’s worth keeping.

Tell us where your team feels slow and we’ll give you a straight answer on what it’s costing, what’s worth fixing, and what to leave ugly, within 48 hours.

  • technical debt
  • engineering cost
  • modernization
FAQ

Common questions, answered

What does technical debt actually cost a business?
It costs developer time first. Stripe's research found engineers spend about 42% of their week on maintenance and bad code. McKinsey found CIOs estimate tech debt at 20-40% of their whole technology estate's value. For a 10-person team paying a 20% debt tax, that's roughly $340K a year in salary spent servicing debt instead of shipping.
How do you calculate the cost of technical debt?
Start with the developer-time tax. Estimate the share of engineering capacity lost to working around debt (surveys put it near 20-40%), multiply by your fully-loaded developer cost, and multiply by headcount. A team of 10 at a 20% tax and a $170K loaded cost per engineer loses about $340K a year. Add the harder-to-price drag on velocity, reliability, and security on top.
Is all technical debt bad?
No. Some code is fine being ugly forever. Debt only costs you when it sits on a path you actively change or that carries real blast radius if it breaks. A stable internal script nobody touches can stay messy for a decade at zero cost. The debt worth paying down is on your critical, frequently-edited systems, where every change pays the interest again.
How do you decide what technical debt to fix first?
Score each item on two axes: interest rate (how often you pay for it) and blast radius (what breaks if it fails). High interest plus high blast radius gets fixed now. Low interest and low blast radius gets left alone, on purpose. The middle gets scheduled when you're already in that code. Don't refactor debt you rarely touch.
What happens if you ignore technical debt?
It compounds. The interest keeps coming out of every future change, so velocity drops and each release gets slower and riskier. CISQ estimated poor software quality cost the US economy about $2.41 trillion in 2022, with accumulated tech debt near $1.52 trillion of that. Ignored debt also becomes a security liability as unpatched, tangled code ages past support.

See it on your own data.

Book a 30-minute discovery call and we'll walk through your use case.