A technical debt assessment turns the feeling that "we are slowing down" into evidence the board can act on: which debt is costing you delivery speed, which is creating risk, and which is safe to leave alone. Most teams know they carry debt. In the 2024 Stack Overflow Developer Survey, the most recent edition to put the question to developers, "amount of technical debt" was the single most cited frustration among professionals, named by 62.4 percent of respondents, with individual contributors and managers agreeing almost exactly. What most teams struggle with is understanding the true cost of that debt and deciding what to address first. This article is a framework for closing that gap: surface the debt across your system, quantify it against signals the business already tracks, and prioritize by cost, not by what offends an engineer.
It is written for the CTO, engineering lead, or technical founder who runs an existing production system, senses that delivery is getting slower and more expensive, and needs to defend a paydown plan to people who do not read code. The approach is deliberately vendor-neutral, so you can act on it with whichever engineering team already knows the system. It also rests on an honest premise: some debt is a rational choice, and the goal of an assessment is governance, not a zero balance.
Key takeaways
- Technical debt is deferred work that buys delivery speed now at a cost later, and some of it is a deliberate, sensible trade.
- An assessment has three steps: surface the debt, quantify it against signals the business already measures, and prioritize by cost and risk.
- Measure what the debt costs, not what the code looks like. Lines, coverage percentage, and a single debt score describe the code, while lead time, change failure rate, and dependency age describe the cost.
- Repay high-interest debt in the code you are actively changing. Leave it alone in the parts of the system nobody has touched in a year.
What technical debt actually is
Technical debt is deferred engineering work that buys delivery speed now at the cost of slower or riskier change later. The metaphor comes from Ward Cunningham: shipping code that is not quite right is like borrowing money. You move faster today, and you pay interest on every future change until you repay the principal by doing the work properly. The principal is the effort to bring a part of the system back to a maintainable baseline. The interest is the recurring tax every later feature pays because that work was skipped.
The word "debt" makes a board hear failure, so it helps to reframe it as financing. Taking on debt can be the correct decision. Martin Fowler's technical debt quadrant sorts debt along two axes, deliberate versus inadvertent and prudent versus reckless, and the deliberate-and-prudent case (shipping a simpler design on purpose to hit a market window, with a plan to revisit it) is a legitimate business move. The problem is not technical debt itself, but debt that neither deliberate nor measure and that quietly accumulates over time.
A baseline helps you name the gap. The international standard ISO/IEC 25010:2023 defines software maintainability through five properties: modularity, reusability, analyzability, modifiability, and testability. Maintainable code, in plain terms, is code a new developer can understand and change safely without fear. Technical debt is the distance between the system you have and that baseline, measured where it actually costs you.
Why technical debt is hard to see
Debt never appears on a feature list, which is why it is easy to underfund. It shows up in the slope of delivery: the same kind of change that took three days last year now takes two weeks, and nobody can point to the line of code responsible. By the time the symptom is undeniable, the interest has been compounding for months.
The common response is to reach for a code metric. Teams count lines, track test coverage, or buy a tool that prints a single "technical debt ratio", a percentage meant to capture the whole system's health. These numbers feel objective, and they are the wrong target. Ninety percent coverage on a module nobody changes tells you nothing useful, while the part of the system you touch every week may have no tests at all. A single composite score hides which debt is expensive and which is harmless, and it invites teams to optimize the number instead of the outcome. The useful question is not how much debt exists in the abstract, but how much it is charging you on the work you are actually doing.
The feeling and the signal
An assessment works by translating the things a CTO feels into signals a board reads. Each symptom below has an observable measure behind it, and each points to one of the six places debt tends to hide.
| What you feel | The observable signal | Where the debt lives |
|---|---|---|
| "Releases keep slipping" | Lead time for a typical change is rising year over year | Code, architecture |
| "Every change feels risky" | Change failure rate and recovery time are climbing | Test |
| "One small feature touches everything" | A single change spans many services or teams | Architecture |
| "We firefight more than we build" | Share of engineering time on unplanned work and incidents | Infrastructure and operations |
| "A forced upgrade is coming" | Components past end-of-life, count of known vulnerabilities | Dependency and end-of-life |
| "Only one person understands that" | Onboarding time to a safe change, ownership concentration | Knowledge and bus-factor |
Step 1: Surface it
Surfacing debt starts with an inventory of where it lives. Static analysis tools have a role, but they are a floor, not the answer. They find duplication and complexity in code, and they are blind to architecture, knowledge, and operational debt entirely. The richest source is the engineers themselves, who can tell you in an afternoon which parts of the system they dread touching and why. Debt clusters in six recognizable categories.
- Code debt: duplication, dead code, and tangled modules everyone is afraid to change. This is the gap against the ISO/IEC 25010 maintainability properties above.
- Architecture debt: structural choices that no longer fit the load or the roadmap, such as wrong service boundaries, a shared database two teams fight over, or coupling that turns one feature into a multi-team project.
- Dependency and end-of-life debt: frameworks and libraries years behind, packages no longer maintained, a runtime or operating system past its supported life and heading for a forced upgrade.
- Test debt: missing, slow, or flaky tests, and the low release confidence that follows, which pushes teams back toward manual regression.
- Infrastructure and operations debt: manual deploys, servers no one can reproduce, no infrastructure as code, and missing monitoring that leaves you blind until a customer reports the outage.
- Knowledge and bus-factor debt: undocumented systems and single-owner subsystems, where delivery stalls the moment one engineer is on leave.
The output of this step is a plain list, grouped by category, of the parts of the system that carry debt and a one-line note on how each hurts. Nothing gets scored at this stage, because the point is only to draw the map.
Step 2: Quantify it
Quantifying debt means attaching each item on the map to a number the business already understands, or can start measuring. The honest version of this step uses a panel of real operational signals and resists fusing them into one invented index. A board does not act on statements like "the code is messy", but on "lead time for a typical change has doubled in twelve months".
For delivery cost, the most established signals are the DORA software delivery metrics, maintained by the DORA research program at Google Cloud. Three of them measure throughput (change lead time, deployment frequency, and failed deployment recovery time) and two measure instability (change fail rate and deployment rework rate), so together they show how fast you ship and how safely. Tracked over time, they turn "we feel slower" into a trend line. To these, add the share of engineering time spent on unplanned work and rework, the clearest expression of interest being paid, and incident frequency in the areas your inventory flagged.
For dependency and end-of-life debt, the risk is concrete and countable. The 2026 Open Source Security and Risk Analysis report from Black Duck found that 92 percent of codebases contained components four or more years out of date, and 87 percent contained a known vulnerability. The security community has raised where this sits. In the OWASP Top 10:2025, the former Vulnerable and Outdated Components category was widened into A03, Software Supply Chain Failures, which ranks third, and half of the practitioners surveyed placed it first on the list. The signal here is a count: how many of your dependencies are past end-of-life, unmaintained, or carrying a published vulnerability. A platform reaching end of life is the sharpest version of this, and our guide to planning a Drupal 10 migration works through one current example.
For knowledge debt, two measures work well: how long a new hire takes to ship a safe change to production, and how concentrated commit history and ownership are in a single person. Both convert "tribal knowledge" into something a board can see.
One caution holds this step together. These are directional indicators, not a precise cost figure, and presenting them as exact would repeat the mistake of the single debt score. Their job is to make debt legible and comparable, so leadership can weigh it against the other things competing for the same budget.
Step 3: Prioritize it
Once technical debt has been identified and measured, prioritization should focus on business impact, not code cleanliness. The goal is not to eliminate debt but to identify which debts charge the highest interest and refinance those first.
The highest-interest debt sits under active development and on the critical path: the code your team changes every week, the service every feature has to pass through, the dependency whose forced upgrade is months away rather than years. Debt here is taxed constantly, so repaying it pays off quickly. Low-interest debt sits in the corners of the system nobody touches. A poorly structured module that has not changed in two years and sits behind a stable interface is likely costing you very little, and rewriting it for elegance alone is its own form of waste.
This also settles the question of how to repay. A full feature freeze to pay down all the debt is almost never the right move. It stalls the business, and without prioritization a team cannot tell when "done" has been reached, so the freeze drags. The durable pattern is to allocate a steady share of capacity, often expressed as a percentage of each cycle, to the highest cost-and-risk items, and to repay incrementally while the business keeps shipping. Large rewrites deserve particular skepticism. They discard hard-won working knowledge, run long, and tend to reproduce the original debt alongside fresh debt of their own. Incremental refactoring of the highest-interest areas almost always beats a big-bang rewrite.
Technical debt and AI-assisted development
There is a newer reason to take an assessment seriously: your debt level is becoming a gate on how safely you can adopt AI-assisted development. Coding assistants work best on systems that are well-structured, documented, and covered by tests, because those are the systems where a generated change can be checked quickly and trusted. That is close to the central finding of the September 2025 DORA report, which surveyed nearly 5,000 technology professionals and concluded that AI does not repair a team but amplifies what is already there, so strong teams get stronger while struggling teams watch their existing problems intensify. The same report found AI adoption associated with higher delivery throughput, reversing the negative relationship it measured in 2024, while the negative relationship with delivery stability held, and it recorded 30 percent of developers reporting little or no trust in AI-generated code.
Code-level evidence points the same way. GitClear's analysis of 623 million code changes from 2023 to 2026 (the 2026 figures are year-to-date) found duplicated code blocks up 81 percent, copy-paste within a single commit up 41 percent, and error-masking constructs up 47 percent, while refactoring line moves fell 70 percent and long-term maintenance of existing code fell 74 percent. The data is correlational and comes from a code-analytics vendor, so it is a trend to watch and not proof that AI causes debt. The practical takeaway is that paying down structural and test debt is now a prerequisite for getting value from AI tools, not a separate project.
Frequently asked questions
What is a technical debt assessment?
A technical debt assessment is a structured review that surfaces where deferred engineering work lives in a system, quantifies its ongoing cost against observable delivery and risk signals, and ranks it so leadership can decide what to repay and when. It looks at the whole system over time rather than a single change, and its output is a prioritized paydown plan a non-technical board can read.
How do you measure technical debt?
Not by lines of code, test coverage, or a single composite score, which measure the code rather than its cost. Measure it by the interest it charges. Delivery metrics such as lead time, deployment frequency, change failure rate, and recovery time show how velocity and stability are moving. To those, add the share of engineering time lost to unplanned work, the age of your dependencies and any known vulnerabilities, and how long a new hire takes to ship safely. Track these on the parts of the system you actually change.
How much technical debt is acceptable?
There is no zero target, and aiming for one usually means over-engineering and missed deadlines. Acceptable debt is debt you took on deliberately, can explain, and whose interest is not throttling delivery or creating unacceptable risk. The number that matters is the trend, not the balance: debt growing faster than you repay it is the warning sign.
Should we pause feature work to fix technical debt?
Almost never with a full freeze. A debt-only stop stalls the business and rarely ends cleanly. Allocate a steady portion of each cycle to the highest cost-and-risk items and repay incrementally, so the business keeps shipping while the interest rate comes down.
How is a technical debt assessment different from a code review?
A code review checks a specific change against standards, line by line. A technical debt assessment looks at the whole system over time, ties what it finds to business cost and risk, and produces a prioritized plan a non-technical board can act on. One is tactical and local, the other strategic.
From a feeling to a number you can defend
An assessment does not make technical debt disappear, and it is not meant to. It replaces a vague concerns with a ranked list of the debts charging you the most, expressed in signals your board already trusts, so the next budget conversation starts from evidence rather than instinct. Our framework for scoping and defending a web platform budget shows how to bring that list into the conversation. The same discipline of evaluating a system honestly is what a platform audit applies before you commit to a CMS. Your debt level also decides how safely you can adopt AI tooling, the subject of our guide on AI-ready websites. If you want an independent read on what your system is actually costing you and what to repay first, our consulting and advisory service is built for exactly that. To talk it through, contact us.
Keroberos is a web technology consultancy that advises businesses on platform selection, commissions and delivers WordPress and Drupal builds, and provides staff augmentation for development teams. To discuss your technical debt and platform health, contact us.