The Complete Taxonomy of Technical Debt
12 distinct categories of tech debt, from messy code to AI-generated shortcuts. Identify what is slowing your team down and learn which types cost the most to fix.
Beyond "Messy Code"
In 1992, Ward Cunningham coined the term "technical debt" to explain to non-technical stakeholders why software sometimes needs rework. His original metaphor was simple: shipping imperfect code is like borrowing money. It lets you move faster now, but you pay interest on it until you clean it up.
Three decades later, the concept has expanded far beyond what Cunningham imagined. Tech debt is not just about messy code. It lives in your architecture, your tests, your documentation, your dependencies, your deployment pipelines, and -- as of 2025 -- in the AI-generated code your team accepts without reviewing.
Understanding the different types of tech debt is the first step toward managing it. Each type has different causes, different costs, and different remediation strategies. A team that treats all debt the same will waste effort fixing the wrong things first.
Why 12 Types?
Most teams only track one or two types of debt. They fix code smells and ignore the architecture rot underneath. Or they update dependencies but never write the missing tests. This taxonomy covers all 12 categories so you can see the full picture -- and prioritize what actually matters for your team.
The 12 Types of Technical Debt
Each type includes a description, a real-world example, and a severity rating. Severity reflects how expensive the debt becomes if left unaddressed over 12 months.
1. Code Debt
The most visible type. Duplicated logic, poor naming, overly long functions, inconsistent formatting, and dead code. Every developer has seen it. It slows down reading, reviewing, and debugging.
Example: A 2,000-line "utility" file with 40 functions, half of which duplicate logic from other modules. New developers cannot tell which function to use, so they add a 41st.
2. Architecture Debt
The most expensive type. Wrong design patterns, tight coupling between modules, a monolith that should be services (or 67 microservices that should be a monolith). Architecture debt constrains every feature you build on top of it.
Example: An e-commerce platform where the payment, inventory, and shipping modules share a single database with no API boundaries. Changing the inventory schema breaks checkout.
3. Design Debt
Poor abstractions, leaky interfaces, and wrong responsibilities. When classes or modules know too much about each other's internals, every change ripples outward. Design debt lives between architecture (macro) and code (micro).
Example: A "User" class that handles authentication, profile rendering, email sending, and permission checking. Changing the email provider requires modifying the User class.
4. Testing Debt
Missing tests, flaky tests, tests that only cover happy paths, and test suites so slow nobody runs them locally. Testing debt creates a vicious cycle: without tests, developers fear changes; fearing changes, they avoid refactoring; without refactoring, debt grows.
Example: A payment processing module with 12% test coverage. The team deploys on Tuesdays only because that gives them the rest of the week to catch bugs manually before the weekend.
5. Documentation Debt
Missing READMEs, outdated API docs, no architecture decision records (ADRs), and tribal knowledge trapped in one person's head. Documentation debt is invisible until someone leaves the team or a new hire spends three days figuring out what should take 30 minutes.
Example: The only person who understands the billing reconciliation system is on vacation. A production bug arrives. The team spends 6 hours reading code that would have taken 20 minutes with a system diagram.
6. Infrastructure Debt
Manual deployments, snowflake servers configured by hand, outdated operating systems, no infrastructure-as-code, and "works on my machine" environments. Infrastructure debt makes every release risky and every environment unique.
Example: Production runs on a manually configured server that was set up 4 years ago. Nobody remembers all the configuration tweaks. When it crashes, recovery takes 8 hours instead of 8 minutes.
7. Dependency Debt
Outdated libraries, abandoned packages still in production, pinned versions from years ago, and transitive dependencies with known CVEs. Dependency debt is a ticking time bomb -- it is fine until it is catastrophic.
Example: An app still using a logging library that was abandoned in 2021. It has 3 known CVEs. Upgrading requires changing 200+ import statements because the API changed completely in v3.
8. Database Debt
Missing indexes on frequently queried columns, no migration system, schema inconsistencies, stored procedures with business logic, and tables with 200+ columns. Database debt is especially dangerous because it is hard to refactor safely in production.
Example: A "customers" table with 187 columns including "temp_flag", "old_status", and "notes_backup_2019". Schema changes are applied by hand via SSH. There is no rollback plan.
9. API Debt
Inconsistent endpoint naming, no versioning strategy, undocumented breaking changes, mixed response formats (some return arrays, some return objects), and endpoints that return 200 OK with an error message in the body.
Example: An API with endpoints named /getUsers, /api/v2/orders, and /product_list. Three naming conventions. No versioning. Mobile and web clients parse responses differently.
10. Security Debt
Unpatched vulnerabilities, hardcoded credentials, weak authentication, missing input validation, and security practices that were "good enough" five years ago. Security debt is unique because the cost of ignoring it is not slower features -- it is a breach.
Example: An admin panel protected by a single shared password stored in a config file. No MFA, no audit logging, no session expiration. The password has not been rotated since the original developer left.
11. Process Debt
No code review process, no CI/CD pipeline, manual testing only, no branching strategy, and deployments that require a specific person to run a specific script on a specific machine. Process debt multiplies the cost of every other type.
Example: Deployments happen by SSH-ing into production and running a shell script. Only two people know the steps. One is on parental leave. The other is in a different time zone.
12. AI-Generated Debt
The newest category. Hallucinated dependencies, copilot clutter, unreviewed AI-generated code, boilerplate bloat, and pattern divergence from your codebase's established conventions. AI tools produce code faster than humans can review it, creating a new class of debt at unprecedented scale.
Example: A developer accepts 200 lines of AI-generated code that imports a package called "fast-xml-validator" -- a hallucinated dependency that does not exist on npm. The build fails in CI but passes locally because a cached version exists.
Typical Remediation Cost by Type
Not all debt costs the same to fix. Architecture and security debt can require months of work, while documentation and code debt can often be addressed incrementally. This chart shows relative remediation effort on a 0-100 scale.
Relative remediation cost index (higher = more expensive to fix). Based on industry averages and CISQ data.
Which Type Are You Dealing With?
Use these questions to quickly identify the dominant type of debt in your codebase. Most teams have 3-4 types active at once, but there is usually one that causes the most pain.
"Developers are afraid to change this file."
This is likely Code Debt or Testing Debt. Fear of change means the code is hard to understand, tightly coupled, or has no safety net of tests.
"Small features take weeks instead of days."
This points to Architecture Debt or Design Debt. When the foundation is wrong, everything built on top costs more.
"New hires take months to become productive."
This is almost always Documentation Debt combined with Process Debt. Knowledge is trapped in people's heads and setup is manual.
"Every deployment feels risky."
This indicates Infrastructure Debt and Process Debt. If deployments are manual, untested, or irreversible, each one is a gamble.
"We keep getting security audit findings."
Direct Security Debt and Dependency Debt. Recurring audit failures mean systemic gaps, not one-off oversights.
"AI tools are writing more code than we can review."
Classic AI-Generated Debt. When the volume of AI output exceeds review capacity, unverified code enters the codebase at scale.
Keep Exploring
Specialized Debt Deep Dives
In-depth guides for the most common and impactful categories of technical debt. Each page covers root causes, detection strategies, and proven remediation approaches.
API Debt
Versioning strategies, contract consistency, REST and GraphQL anti-patterns, and API governance practices.
Database Debt
Schema evolution, migration strategies, query performance debt, and data architecture patterns.
DevOps & Infra Debt
CI/CD pipeline debt, infrastructure as code gaps, deployment complexity, and operational tooling.
Dependency Management
Outdated packages, version conflicts, transitive dependency risks, and update strategies.
Security & Supply Chain
Vulnerability management, supply chain security, dependency auditing, and security automation.
Code Review for Debt
Using code reviews as a systematic tool for identifying and preventing technical debt accumulation.
Modern & Emerging Debt Categories
As technology evolves, new categories of technical debt emerge. These modern debt types are increasingly relevant in cloud-native, AI-driven, and platform-centric organizations.
UX & Design Debt
Accessibility gaps, design system rot, CSS bloat, responsive breakage, and frontend performance issues that degrade user experience.
Cloud Cost Debt
Over-provisioned resources, zombie instances, vendor lock-in, and missing FinOps practices draining your cloud budget silently.
Platform Engineering Debt
Internal developer platform quality issues, DX friction, golden path decay, and tooling rot with a multiplier effect across all teams.
Observability Debt
Alert fatigue, SLO gaps, metric naming chaos, missing traces, and dashboard sprawl preventing effective incident response.
Compliance & Regulatory Debt
GDPR, SOC 2, HIPAA, and PCI-DSS gaps including audit readiness issues, data privacy violations, and outdated security policies.
ML & Data Debt
Model drift, training data quality, ML pipeline fragility, feature store management, and data governance gaps in ML systems.
Strategy & Decision Frameworks
Beyond categorizing debt, these frameworks help you measure, decide, and act on technical debt strategically.
Measurement Frameworks
SQALE, ISO 25010, CAST, and Code Climate compared. Learn which measurement framework fits your organization.
Rewrite vs Refactor
Decision framework for the hardest question in tech debt: fix what you have or start over? Includes Strangler Fig and other patterns.
Architectural Decision Records
Document the why behind architecture choices. Templates, tooling, and practices that prevent architecture drift.
M&A Technical Debt
Due diligence checklists, post-merger integration playbooks, and strategies for consolidating acquired codebases.
Prompt Engineering Debt
Prompt rot, LLM version drift, hallucination-prone prompts, cost creep, and the emerging challenge of managing AI prompts as code.
Tech Debt Myths
Common misconceptions about technical debt that prevent teams from addressing it effectively.
Governance Policy
Establishing organizational policies and guardrails for managing technical debt at scale.
History of Tech Debt
The origin and evolution of the technical debt metaphor from Ward Cunningham to modern interpretations.
Frequently Asked Questions
Start with whatever is causing the most pain right now. If deployments fail regularly, fix infrastructure and process debt. If bugs keep reappearing, fix testing debt. If features take 3x longer than expected, look at architecture debt. The "right" order depends on your team's specific situation. Use the decision helper above to identify your dominant type, then use a prioritization framework like RICE or Impact/Effort to rank specific items.
Yes, and most mature codebases do to some degree. The question is not whether you have each type but how severe each one is. A healthy codebase might have minor documentation debt and minor code debt while having zero security debt. An unhealthy codebase has critical levels across 5 or more categories. The taxonomy helps you see the full picture rather than fixating on just the types that are most visible (usually code debt).
Yes, for three reasons. First, volume: AI tools generate code faster than humans, so debt accumulates faster. Second, hallucinations: AI can introduce dependencies, patterns, or APIs that do not exist. Third, review blindness: developers trust AI output more than they should and review it less carefully than human-written code. Studies show developers accept AI suggestions 30% of the time without meaningful review. That 30% is a direct pipeline for unexamined debt.
Use analogies from the physical world. Code debt is like a messy office -- you can still work, but you waste time finding things. Architecture debt is like a building with a cracked foundation -- every renovation is more expensive. Security debt is like a broken lock on the front door -- it is fine until it is not. Infrastructure debt is like running a factory with no maintenance schedule. Non-technical leaders respond best to cost and risk framing, not technical descriptions.
Not necessarily. Start by tracking the 3-4 types that cause the most pain for your team. Use labels or tags in your issue tracker to categorize debt items. Over time, you will see patterns -- maybe 60% of your debt is testing and documentation, which tells you where to focus. The taxonomy is a lens for understanding, not a mandate for 12 separate tracking systems. Keep it simple and useful.
They compound. Architecture debt makes code debt worse because developers write workarounds for structural problems. Testing debt makes every other type more dangerous because there is no safety net for changes. Process debt slows down the remediation of everything else. Documentation debt means the team does not even know where the other debt is. The most effective teams fix the "multiplier" types first -- process, testing, and infrastructure -- because that makes fixing everything else cheaper and safer.
Start Tackling Your Debt
Now that you can name it, you can fix it. Explore proven techniques and measure your progress.