blog
/
Strategy
Strategy
October 5, 2026

Technical Debt Examples: 12 Cases and the Signals Teams Missed

In 2012, a trading firm lost more than $460 million after 45 minutes of runaway orders, partly because of code it had stopped using nine years earlier. The cases below show how implementation choices and weak operational controls can make later changes carry the costs the original work deferred.

Ward Cunningham's original debt metaphor captures the trade-off: shipping an initial implementation buys time, but deferring cleanup makes future work carry the cost. Below are 12 real-world examples, grouped by where the debt lived. Six are documented incidents, sourced to government and company records. Six are illustrative composites of common patterns, labeled as such. Each covers the cost, the early signal, and the first repayment move.

What Counts as a Technical Debt Example?

Technical debt is what a shortcut keeps costing you after it ships: the extra work, outages, or blocked changes you pay for later because a choice saved time now. A technical debt example is any specific shortcut where you can point at the interest.

Common examples of technical debt include:

  • Hardcoded secrets and environment settings
  • Copy-pasted logic that has to be fixed in five places
  • Test debt from suites skipped to hit a release date
  • Outdated dependencies nobody can upgrade
  • A database shared between services
  • A manual release process

As with financial debt, borrowing isn't always a mistake. Martin Fowler's technical debt quadrant sorts debt on two axes: deliberate (the team knows it's borrowing) or inadvertent (it spots the debt later), and prudent or reckless. Our guide to the types of technical debt covers that taxonomy.

Code-Level Technical Debt Examples

Code debt appears in implementation details such as duplicated rules, hardcoded settings, and functions that mix unrelated responsibilities.

1. The 600-line function every new feature touches

An illustrative composite. A B2B app prices quotes in one function, applyPricingRules(). Regional tax, contract discounts, promo codes, and a special rule for one large customer each landed as another if. It's now past 600 lines and sits on the checkout path.

Small pricing changes get estimated in weeks, and a fix in one rule breaks another. The early signal is in version control: the same file shows up in most feature PRs, and reviewers approve its diffs without reading them. The first repayment move is to pin current behavior with characterization tests, then extract one rule family at a time.

2. Hardcoded secrets and configuration

Also illustrative. A database password lands in a config file "just for staging," an API key goes into a constant, and a region name gets baked into a dozen call sites.

The interest is security debt plus friction: rotating a credential needs a code change and a deploy, and anyone with repo access has the key. Often the first sign is "can we rotate this?" getting the answer "after the next release," or a secret scanner lighting up on repository history. Repayment means a secrets manager, then rotating everything ever committed, since git history keeps it.

3. Y2K: a two-digit shortcut repeated for decades

Storing a year in two digits saved storage and operating cost, but discarded the century. The same value could then mean 1900 or 2000, leaving date calculations and comparisons ambiguous. That failure mechanism is documented in the GAO's 1997 assessment guide.

The Senate's Y2K committee, in its February 2000 final report, cited a Commerce Department estimate that U.S. government and businesses spent about $100 billion on the problem. Per committee testimony, many firms and agencies "discovered during Y2K preparation that IT inventory was inaccurate or absent." The fix starts with finding every place the shortcut lives.

Architecture Debt Examples

Architecture debt, along with the design debt inside individual services, can arise when decisions made for an earlier system constrain its later growth.

4. Three services writing to one shared database

Back to an illustrative composite. A monolith gets split into Orders, Billing, and Notifications services, but the split stops at the code. All three still read and write the same database. Billing adds columns to the orders table, Notifications polls its status column, and nobody owns the schema.

Before and after diagram: three services share one orders database with no owner, so renaming a column takes three teams; after repayment, Orders owns the database and the others use its API or events

The cost is coordination. Renaming a column needs three teams and one coordinated release. A slow query from one service degrades the other two.

The early signals are social before they're technical:

  • Schema migration PRs need approvals from teams that don't own the change.
  • Release calendars get planned around database migrations.
  • "Who else reads this table?" takes a Slack thread to answer.

Repaying it starts with a map of which services depend on each database table. Then give each table one owning service, and have everyone else read through that owner's API or its events.

5. HealthCare.gov (2013): many contractors, no architectural owner

HealthCare.gov launched on October 1, 2013, and "users were met with website outages and technical malfunctions," according to the HHS Office of Inspector General's case study. CMS tied 60 contracts to building and running it, and by February 2014 nearly $800 million had been obligated across them to develop the Federal Marketplace, per a separate OIG review of those contracts.

The OIG identified unclear leadership as the most critical problem. Early on, no single official below the CMS Administrator had responsibility for the Federal Marketplace, and senior leadership never assigned clear overall business ownership. The debt sat in the seams between components that different contractors built, and nobody owned the seams.

CMS received 18 detailed warnings between July 2011 and July 2013, but the assessments did not reach the same decision makers. TurningPoint Global Solutions presented its reports only to technical staff; McKinsey presented its recommendations only to senior officials. The cheaper move would have come before launch: name one architectural owner, and record who owns each decision and why.

6. Twitter's Rails monolith and the Fail Whale (2010 to 2013)

After World Cup traffic caused brief outages in 2010, Twitter's engineering review found a Rails monolith with about 200 contributors and storage already at its throughput limit. Adding machines was no longer enough. The team's 2013 account traces the rebuild to those constraints; its June 2010 status post had already warned of further outages under unprecedented traffic.

The cost was availability at the moments that mattered most, then a multi-year rebuild. Twitter replaced the Ruby monolith with JVM services that could launch and deploy independently. In August 2013, the rebuilt system recorded a one-second peak of 143,199 Tweets per second.

The warning signs were a system too large for individual engineers to understand fully and a scaling response centered on adding hardware.

In examples 4 to 6, a code-quality scan alone would not give the full picture of runtime dependencies and ownership. The problems sat in who wrote to which table, who owned the integration, and how much load one shared design could carry. That kind of architectural debt is easier to catch when you can see the system as it runs, which we cover below.

Legacy System and Infrastructure Debt Examples

Infrastructure debt collects in the parts nobody ships features on, including the configuration drift between environments that makes staging a poor predictor of production.

7. Southwest Airlines' crew scheduling system (December 2022)

Over the 2022 holidays, Southwest canceled 16,900 flights and stranded more than two million passengers, according to the U.S. Department of Transportation. In Senate testimony, Southwest's chief operating officer distinguished a capacity failure from a software stoppage: the tools kept running, but crew-scheduling processes and technology could not keep up with the volume of changes.

DOT fined Southwest $140 million, plus more than $600 million in refunds and reimbursements, for a total of over $750 million.

In testimony to the same Senate committee, the pilots' union said it had warned the company "since 2014" that "technology and crew scheduling processes were failing." Paying it down starts with testing recovery at worst-day volume, then planning for modernizing the legacy system without stopping operations.

8. Equifax and an unpatched Apache Struts library (2017)

Equifax's online dispute portal ran Apache Struts, a third-party web framework, with a known flaw. The flaw let attackers run commands on affected systems. The timeline:

  • March 2017: Equifax receives a notice about the vulnerability from US-CERT. On March 10, intruders scan for the flaw and use it to access the portal, though they take no data.
  • May 13, 2017: in a separate incident, attackers get into the still-unpatched portal and start pulling personal data.
  • About 76 days later: the attack is discovered.

Under a 2019 settlement with the FTC, the CFPB and 50 U.S. states and territories, Equifax agreed to pay at least $575 million and potentially up to $700 million for a breach that affected about 147 million people.

The GAO report traces the missed patch to a stale notification list: the notice did not reach the people responsible for installing it. A subsequent network scan also missed the vulnerable portal. Repaying it starts with an inventory of what runs and who owns each piece, which is what a regular tech stack audit produces. Take it down to library versions so a notice reaches the person who patches.

9. The framework stuck past end of support

Another illustrative composite: a customer-facing app runs on a web framework whose maintainers announced an end-of-support date years ahead. The upgrade keeps slipping because a major version jump touches authentication, templates, and half the dependencies.

Once the date passes, upstream security fixes for that release stop, and incompatible dependencies can leave you pinned to older library versions. You can see this one coming years away: a known end date with no funded plan or owner, and dependency alerts the team has learned to ignore. Build the same inventory as example 8 with support dates added, then put the date on the roadmap.

Process and Knowledge Debt Examples

Code scans do not establish who can operate a system or whether a deployment procedure is followed. Check those controls and ownership directly.

10. Knight Capital (2012): dead code and a manual deployment

In late July 2012, Knight Capital rolled out new code to its SMARS order router in stages. The SEC's order shows three kinds of debt lining up:

  • Dead code. Knight stopped using a feature called Power Peg in 2003, but it "remained present and callable."
  • A reused flag. The new code repurposed the flag that used to switch Power Peg on.
  • An unchecked deploy. A technician didn't copy the new code to one of the eight servers, nobody reviewed the deployment, and Knight had no written deployment procedures.

On August 1, the eighth server still ran the old code, and the reused flag woke up Power Peg. Over 45 minutes, it produced more than 4 million executions in 154 stocks, and Knight lost over $460 million. The SEC later imposed a $12 million penalty.

The signal arrived that morning. Before the 9:30 a.m. open, Knight's systems sent 97 emails flagging "Power Peg disabled," but Knight hadn't designed those messages as alerts. The repayment moves: delete dead code instead of leaving it callable, retire flags instead of reusing them, and automate deploys so every server is verified to run the same build.

11. The bus factor of one

Illustrative again. One platform engineer wrote the Terraform modules that stand up every customer environment. Nobody else has changed them in a year, and the documentation is a week-one README.

Knowledge debt and documentation debt travel together here. Changes queue behind one person, incidents stall when they're out, and team morale drops as everyone routes around the module. The signal is easy to pull: one name on nearly every commit in the last year, and runbooks that say "page them." Repayment is pairing someone on the next two changes and writing down the decisions while the author is still around.

Data and AI-Generated Debt Examples

First, a short, illustrative data debt example. A team adds a metadata JSON column to avoid a migration. Several features each write their own shape into it, and two dashboards end up disagreeing on the same number. The fix is a real schema per shape, validated on write.

12. AI-generated code that passes tests but ignores the architecture

The last example is illustrative too. A developer asks a coding assistant to add order-status messages to the Notifications service. The assistant needs the order's status, finds the orders table, and queries it directly, recreating the coupling from example 4. The tests pass because they check behavior, not boundaries, and the diff looks clean in review.

In the 2025 DORA research, 90% of respondents reported using AI at work, while greater AI adoption remained associated with lower delivery stability. The reported gains also depended on the surrounding system: loosely coupled architectures and fast feedback supported improvement; tightly coupled systems and slow processes showed little or none.

Watch for PRs that add cross-service calls to code that was never meant to reach another service. Turning boundaries into CI checks catches many of them, and giving the assistant the architecture decisions before it writes code prevents more.

What These Examples Have in Common (and How to Spot Them Early)

Laid side by side, the 12 technical debt examples look like this.

Example

Where the debt lived

How it surfaced

Early signal

First repayment move

1. 600-line function

Code

Slow, risky pricing changes

Same file in most PRs

Tests, then extract

2. Hardcoded secrets

Code

Rotation needs a deploy

Scanner hits in git history

Secrets manager, rotate all

3. Y2K

Code

About $100B to remediate

No accurate IT inventory

Inventory, then fix

4. Shared database

Architecture

Cross-team migrations

"Who reads this?" has no quick answer

One owner per table

5. HealthCare.gov

Architecture

Launch outages

18 siloed warnings, no owner

Name an owner, record decisions

6. Twitter

Architecture

Outages on traffic spikes

Hardware as the scaling plan

Independently deployed services

7. Southwest

Infrastructure

16,900 canceled flights

Pilots' warnings since 2014

Test at worst-day volume

8. Equifax

Infrastructure

Data on ~147M people exposed

Stale notice recipient list

Inventory versions and owners

9. Framework past end of support

Infrastructure

No security fixes

End date, no funded plan

Inventory, then roadmap the date

10. Knight Capital

Process

$460M+ loss after 45 minutes

97 "Power Peg disabled" emails

Delete dead code, automate deploys

11. Bus factor of one

Process

Work waits on one person

One name on every commit

Pair, document decisions

12. AI-generated coupling

Architecture, via AI code

Instability as volume grows

New cross-service calls

Boundary checks in CI

Three things repeat across the table. Several public cases show how coupling, unclear ownership, and weak operational controls can magnify an incident: an integration nobody owned, a vulnerability notice sent to a stale list, a deploy nobody checked. The dollar figures measure different things and are not comparable costs of technical debt. And the interest got paid in outages, migrations, penalties, and engineers who became single points of failure, not in code.

Here are five ways to identify technical debt early that a leadership team can check this quarter:

  • List the files changed in most of last quarter's PRs, and who can safely change each.
  • For each production datastore, name every service that writes to it. If the answer is unclear, investigate shared ownership and undocumented consumers before changing the schema.
  • Trace where vulnerability notices and automated warnings land, and confirm a current owner reads them.
  • Check that every component with a published end-of-support date has a funded plan.
  • Ask the people who run the system on its worst day what they've been warning about.

Our guide on measuring technical debt covers metrics for tracking debt over time.

Much of the debt above lived between components, and that's the part we built Catio to make visible. Stacks, our view of the system as it runs now, is built from the integrations you connect: AWS and Kubernetes describe what's running, GitHub source code adds the business logic, and VPC Flow Logs turn observed traffic into relationships between components. That makes "which services connect to the shared database?" a question for Archie, our reasoning agent, instead of a Slack thread. When we identify a change worth making, we draft a Recommendation with a target state, a gap analysis, and an implementation plan.

We only see what those integrations cover, and a traffic-based relationship appears only if it falls within the time window you read. Today we support AWS estates at companies past the early-stage startup phase. We also don't replace linters or code review: debt like examples 1 and 2 still gets fixed in the code.

Conclusion

Very little of this debt was secret: HealthCare.gov had 18 documented warnings, Southwest's pilots said they had raised crew scheduling problems since 2014, and Knight's systems sent 97 emails before the open. What failed was getting each warning to someone who owned the fix.

If you want to see what's actually running before you pick which architecture debt to tackle first, chat with the team and bring the system you're most worried about. Frequently Asked Questions

How do you get out of technical debt?

Managing technical debt starts with the debt on your busiest paths. Fix it in slices alongside feature work, and stop adding new debt in the same places. Our playbook for reducing technical debt covers prioritization and running a debt backlog.

How much technical debt is acceptable?

It depends more on where the debt sits than on how much there is. A shortcut in a module nobody has opened in a year can wait. One on a path most releases touch, a security boundary or a shared datastore costs you on every change, so treat it as urgent.

What is another name for technical debt?

Most teams just say tech debt. You'll also hear code debt or design debt for narrower slices, and "cruft" for the general buildup of old, unneeded code.

What are some examples of technical debt in software projects?

The 12 above run from hardcoded secrets and Y2K's two-digit years to Knight Capital's dead code and AI-generated coupling.

Share this Post

Related posts