Konnectedly

Five Technical Debt Examples That Look Identical on a Report and Need Opposite Decisions

⏱ 19 min read📅 October 2026

Every technical debt report looks more or less the same. A list of systems, a column of risk ratings, a rough estimate of remediation effort, and a recommendation that usually resolves to "this needs attention." What the report almost never tells you is that the items on that list are not the same kind of problem. Five systems can each carry a "high debt" rating and need five entirely different responses - one paid down urgently, one left completely alone, one retired without replacement, one monitored quietly, and one addressed only after a triggering event. Getting those five wrong in the same direction costs real money.

The reason the report flattens them is structural. The people who write it are usually measuring what they can measure: code complexity scores, test coverage percentages, library age, open security advisories. Those are real signals. They are just not the whole picture. The business context that decides what any of those signals means - how often the system changes, what breaks when it fails, whether anyone has a plan to replace it, what the engineers who understand it cost to retain - rarely makes it into the same document.

This post describes five specific technical debt examples drawn from patterns that appear repeatedly across application estates. Each one has a different underlying cause, a different cost profile, and a different correct response. The goal is not a framework for scoring them. The goal is to give you enough texture to recognise which one you are looking at before you fund the remediation.

What is technical debt, in terms that connect to a business decision?

The term was coined by Ward Cunningham in 1992, and his original meaning was narrow: debt taken on deliberately, with the intention of paying it back. A known compromise, made under time pressure, with a plan to clean it up later. That meaning has since expanded to cover almost any kind of code quality problem, which is part of why technical debt reports are hard to act on. When everything is debt, nothing is specifically payable.

For the purposes of a business decision, the question is not whether technical debt exists - it always does - but whether the interest being paid on it exceeds the cost of paying it down. That calculation requires knowing what the debt is actually costing: developer hours lost to workarounds, incident response time, the premium paid to hire engineers willing to work in the codebase, delayed features, and failed regulatory audits. A rough figure that many engineering leaders use as a sanity check comes from McKinsey research published in 2022, which found that technical debt consumed between 10 and 20 percent of IT budgets on average, and reached 40 percent of total development capacity in the worst cases. That figure measures self-reported productivity loss across a sample of large organisations - it is not a controlled study - but it gives a ballpark that most CTOs find credible when they look at their own teams.

The five examples that follow are not exhaustive. They are the five patterns that show up most often in an assessment and that most reliably produce the wrong decision when treated as a single category.

Example one: the deliberate shortcut that was never revisited

Every engineering team has made this trade-off. The launch is in three weeks. The right solution requires a database schema change that will take six weeks to test safely. Someone writes a workaround - a translation layer, a data duplication mechanism, a hardcoded assumption - with a comment in the code that says "TODO: fix this properly after launch." The launch happens. The team moves to the next thing. Two years later, nobody remembers why the workaround is there, the person who wrote it has left, and the comment is still in the code.

This is shortcut debt, and in its early stages it is almost always the right call. The problem is the second half of the bargain - the cleanup - that never happens. Organisations that are good at this kind of debt maintain an explicit backlog of known shortcuts, with the business context attached: what was deferred, why, what it would cost to address, and what happens if it is not. Organisations that are not good at it accumulate a codebase full of workarounds that nobody can explain.

The correct response to shortcut debt depends entirely on how much the affected system has grown since the shortcut was made. If the system is small and stable, the workaround may be safe to leave indefinitely. If the system has grown and the shortcut is now load-bearing - meaning other code depends on the workaround behaving exactly as it does - addressing it becomes expensive and risky, and the cost compounds with every year it is deferred. The diagnostic question is simple: does the team spend time each month working around this, or do they forget it exists?

Example two: legacy platform debt in a stable system

This is where the most money gets wasted in modernization decisions. A system running on COBOL, or on a version of Java that reached end of life in 2015, or on an on-premises Oracle installation that the vendor will no longer support in two years, shows up in every debt report as high risk. The question is whether that risk is active or theoretical.

Consider the payroll system that has run without a production incident for eleven years. It processes payroll on the last Friday of every month. It has not been changed in three years. The two people who understand it are approaching retirement. It runs on a 2004 version of a database that the vendor no longer patches. Every one of those facts is real. Now ask: when did anyone last need to change this system, and what would happen if it failed on the last Friday of the month?

The answer to the second question - consequences of failure - is what separates urgent action from expensive theatre. If the system is genuinely stable, rarely changed, and the blast radius of a failure is bounded and recoverable, the correct response is often to document it thoroughly, establish a monitoring regime, and defer investment until a triggering event - a vendor forcing the issue, a key person giving notice, a compliance requirement. The modernization cost for a system like this is typically measured in hundreds of thousands of pounds. Spending that money because a report said the platform is old, without asking whether the platform's age is causing harm, is a category error.

The case for acting now is different when the system is on a growth path - when the business is adding features, when volume is increasing, when regulatory requirements are adding complexity. In that scenario, the platform's age is a constraint that gets more expensive with every new requirement. Assess the trajectory, not just the current state.

Example three: test coverage debt in a high-change system

The Stack Overflow Developer Survey consistently shows that the work developers find most draining is not writing new code - it is modifying code they cannot safely test. The fear of breaking something unseen is real, and it has measurable consequences: developers slow down, reviews get longer, releases get batched to reduce the number of times anyone has to touch the system, and incidents increase because changes go out with less confidence than they should.

This kind of debt is invisible on the surface. The system works. Users are not complaining. The incident rate is low, partly because nobody is changing anything. The cost sits inside the engineering team, in the hours spent on manual regression testing, in the delayed releases, in the senior engineers who spend Friday afternoons checking by hand whether this week's change broke something in a module it was never meant to touch.

The business case for addressing test coverage debt is not about the system's current stability - it is about the cost of every future change. If the business has decided this system is in maintenance mode and will not be significantly changed, the absence of tests is an acceptable risk. If the business wants to add features, integrate new channels, or respond to regulatory changes, the absence of tests becomes a tax on every delivery. The figure to establish is not the coverage percentage - it is the hours spent in manual testing per release, multiplied by the number of releases planned over the next two years, minus the cost of building the test suite. That is the return on investment calculation, and it is usually available within a week of looking.

Example four: data model debt in a system forced to serve too many purposes

A customer database built for a single-channel retail business in 2008 did not need to record which channel a customer came from. When the company added an e-commerce channel in 2012, someone added a column to the existing table. When they added a mobile app in 2016, someone added another. When they acquired a competitor in 2019, the two customer databases were merged by writing a reconciliation script that runs every night. By 2024, the "customer" table has 47 columns, eleven of which are null in more than 80 percent of rows, three of which contain values that are only meaningful if you know which channel the record came from, and the overnight reconciliation script takes six hours and fails roughly once a month.

This is data model debt, and it is among the most expensive kinds to address because the fix is not a code change - it is a data migration. Changing a schema that other systems depend on requires coordination across every consuming application, extensive testing of edge cases, and usually a parallel running period in which both old and new structures coexist. The cost is real and the duration is long.

The correct response to data model debt depends on whether the data itself is the product. For a business that runs on customer data - personalisation, targeting, lifetime value calculation, regulatory reporting - the debt is directly constraining revenue and compliance. The case for addressing it is proportional to the value of the decisions the data supports. For a business that uses the data only for order fulfilment and basic CRM, the debt may be manageable in place, with targeted improvements to the reconciliation logic rather than a full restructuring.

The Martin Fowler writing on refactoring and data migration patterns is worth reading in this context - not for the implementation detail, but for the honest description of how long this kind of work takes and how often the first estimate turns out to be optimistic.

Example five: dependency debt and the third-party forcing function

Your application uses an open-source library that was last committed to in 2019. A security researcher publishes a critical vulnerability in it in March. The library is not maintained. There is no patch. You have three options: replace the library, build your own patch and maintain a fork, or accept the risk and document the compensating controls. None of those options are free, and none of them were on your roadmap.

Or: your application runs on a commercial platform whose vendor announces a major version change with a migration deadline. The old version will reach end of support in eighteen months. The migration requires changes to how your application communicates with the platform. The estimate comes in at nine months of engineering time. You have sixteen months. You are not in trouble yet, but you are not comfortable either.

Dependency debt is the category most likely to produce a decision under pressure, with less time and less information than the team would like. The organisations that handle it best are the ones that audit their dependency landscape on a regular cadence - not to fix everything, but to know in advance which dependencies are at risk and how hard each one would be to replace. The OWASP Dependency-Check project and the National Vulnerability Database are both freely available and give a reasonable picture of which libraries in a codebase have known exposures. Using them is not a remediation - it is a warning system, and the difference matters.

The wrong response to dependency debt is to treat every outdated library as an emergency. The right response is to triage by exploitability and by coupling: how exposed is this vulnerability, and how deeply is this library embedded in the system? A library that handles a narrow, internal function and has no known path to exploitation from outside the network is different from a library that handles authentication or payment processing.

Which of these five technical debt examples are you actually looking at?

The practical starting point is not a scoring model. It is four questions, applied to each item on the debt report:

First, how often does someone need to change this system? A system touched daily by developers needs clean, testable code. A system touched twice a year does not need to meet the same standard.

Second, what breaks when this system fails, and how long does it take to recover? A failure that affects revenue in real time or that the business cannot recover from manually is different from a failure that causes inconvenience and can be corrected in the next batch run.

Third, is this system on a growth path? A system being asked to do more - more volume, more features, more integrations, more regulatory scope - has a different debt tolerance than a system in maintenance mode.

Fourth, is there an external event that could force the decision? A vendor's end-of-support date, a security vulnerability, a regulatory change. These create deadlines that do not care about the business's preferred investment cycle.

A system that scores low risk on all four questions - rarely changed, low consequence of failure, in maintenance mode, no external forcing function - is a system whose debt can be left alone, and doing so is the correct answer. A system that scores high on any one of them, and especially on the combination of "changed frequently" and "high consequence of failure", is a system where debt is costing you money today and the cost compounds with every quarter you defer.

The complication is that most organisations do not have this information at a system level. They have the debt report. They do not have the change frequency data, the incident consequence analysis, or the dependency audit. Getting to those four answers takes work - typically two to four weeks of structured assessment per application cluster - and that work is what turns a report into a decision.

Konnectedly approaches assessments from exactly this position: determining which kind of debt each system carries, scoring it against those four questions, and producing a recommendation that includes "leave it alone" where the evidence supports it.

Frequently Asked Questions

What is a technical debt example in plain terms?

A common example is a payroll system still running on COBOL that works without failure but that only two people in the organisation know how to modify. The code is decades old, the language is scarce, and every change takes ten times longer than it should. That is technical debt: a past decision whose cost is being paid in the present.

What are the five main types of technical debt?

The five types are: deliberate shortcut debt (a known compromise made under time pressure), legacy platform debt (a system that has outgrown its original technology), test coverage debt (code that works but cannot be safely changed without risk), data model debt (a schema built for one purpose now forced to serve another), and dependency debt (reliance on third-party libraries or vendors that are no longer supported or have changed their terms).

How do you tell the difference between technical debt worth fixing and debt worth ignoring?

Ask two questions: how often does someone need to change this system, and what happens if the change goes wrong? Debt in a system touched daily by developers and customer-facing in its failures is worth paying down. Debt in a stable system changed once a year with a contained blast radius is usually worth leaving alone. Change frequency and failure consequence are the two variables that matter most.

What does technical debt cost a company in real terms?

McKinsey research published in 2022 found that technical debt consumes between 10 and 20 percent of an average IT budget, and that in some organisations the figure reaches 40 percent of total development capacity. The cost shows up as delayed features, longer testing cycles, higher incident rates, and the premium paid to find engineers willing to work in ageing codebases.

Can technical debt ever be left alone deliberately?

Yes, and it often should be. If a system is stable, rarely changed, and not on a growth path, paying down its debt may cost more than it saves. The honest answer for a significant portion of any application estate is to leave the debt in place, monitor the system, and spend the budget on the parts of the estate where debt is actively slowing the business down.

How long does it take to pay down technical debt?

There is no universal answer, and anyone who gives you one without seeing the codebase is guessing. Targeted debt reduction in a single module - improving test coverage, upgrading a dependency - can take weeks. Addressing structural debt across a large system can take two to four years of sustained investment. The more useful question is not how long, but whether the return justifies starting at all.

Who is responsible for technical debt in an organisation?

Technical debt accumulates under engineering decisions but is almost always caused by business decisions: launch dates moved forward, budget cuts to testing, years of deferring upgrades. Ownership sits with whoever controls the trade-offs - which usually means the CIO or CTO, with accountability upward to the executive team that sets the conditions under which those trade-offs get made.

What is the difference between technical debt and a legacy system?

A legacy system is defined by its position in the organisation - it is a system the business depends on but can no longer easily change or replace. Technical debt is a property of code or architecture - the accumulated cost of past shortcuts. A legacy system almost always carries technical debt, but a new system can carry significant technical debt too. The two terms describe different things and should not be used interchangeably.

An assessment of your application estate would identify which of these five debt types each system carries and produce a clear recommendation on where to invest, where to monitor, and where to leave things alone.

Book a call →

Questions

What is a technical debt example in plain terms?
A common example is a payroll system still running on COBOL that works without failure but that only two people in the organisation know how to modify. The code is decades old, the language is scarce, and every change takes ten times longer than it should. That is technical debt: a past decision whose cost is being paid in the present.
What are the five main types of technical debt?
The five types are: deliberate shortcut debt (a known compromise made under time pressure), legacy platform debt (a system that has outgrown its original technology), test coverage debt (code that works but cannot be safely changed without risk), data model debt (a schema built for one purpose now forced to serve another), and dependency debt (reliance on third-party libraries or vendors that are no longer supported or have changed their terms).
How do you tell the difference between technical debt worth fixing and debt worth ignoring?
Ask two questions: how often does someone need to change this system, and what happens if the change goes wrong? Debt in a system touched daily by developers and customer-facing in its failures is worth paying down. Debt in a stable system changed once a year with a contained blast radius is usually worth leaving alone. Change frequency and failure consequence are the two variables that matter most.
What does technical debt cost a company in real terms?
McKinsey research published in 2022 found that technical debt consumes between 10 and 20 percent of an average IT budget, and that in some organisations the figure reaches 40 percent of total development capacity. The cost shows up as delayed features, longer testing cycles, higher incident rates, and the premium paid to find engineers willing to work in ageing codebases.
Can technical debt ever be left alone deliberately?
Yes, and it often should be. If a system is stable, rarely changed, and not on a growth path, paying down its debt may cost more than it saves. The honest answer for a significant portion of any application estate is to leave the debt in place, monitor the system, and spend the budget on the parts of the estate where debt is actively slowing the business down.
How long does it take to pay down technical debt?
There is no universal answer, and anyone who gives you one without seeing the codebase is guessing. Targeted debt reduction in a single module - improving test coverage, upgrading a dependency - can take weeks. Addressing structural debt across a large system can take two to four years of sustained investment. The more useful question is not how long, but whether the return justifies starting at all.
Who is responsible for technical debt in an organisation?
Technical debt accumulates under engineering decisions but is almost always caused by business decisions: launch dates moved forward, budget cuts to testing, years of deferring upgrades. Ownership sits with whoever controls the trade-offs - which usually means the CIO or CTO, with accountability upward to the executive team that sets the conditions under which those trade-offs get made.
What is the difference between technical debt and a legacy system?
A legacy system is defined by its position in the organisation - it is a system the business depends on but can no longer easily change or replace. Technical debt is a property of code or architecture - the accumulated cost of past shortcuts. A legacy system almost always carries technical debt, but a new system can carry significant technical debt too. The two terms describe different things and should not be used interchangeably.