4 Types of Technical Debt
Martin Fowler's technical debt quadrant categorises debt by how it was created and how knowingly it was taken on. Understanding the type is the first step to addressing it correctly.
Deliberate and Reckless
This is the most damaging form of technical debt. The team knows good practices exist, consciously chooses to ignore them, and does not plan to address the resulting problems. It is often driven by unrealistic deadlines, poor management understanding of engineering, or a culture that rewards short-term delivery over sustainable pace.
How It Accumulates
- ●Skipping code reviews to ship faster
- ●Disabling failing tests instead of fixing the underlying issue
- ●Copy-pasting logic across services instead of abstracting it
- ●Hardcoding configuration values into application code
- ●Ignoring security vulnerabilities flagged in dependency scans
Consequences
- ▲Exponential increase in bug rate over time
- ▲Engineers spend most time fighting fires rather than building
- ▲Onboarding new engineers becomes extremely slow
- ▲Fear of making changes prevents necessary improvements
- ▲Business trust in engineering erodes due to constant incidents
How to Address It
This type requires organisational change, not just technical work. Engineering leaders must be empowered to push back on unrealistic timelines and make the cost of reckless debt visible to business stakeholders. ROI calculators like this one help quantify the business case for slowing down.
Deliberate and Prudent
This is the acceptable face of technical debt. A considered decision is made to take on debt with full awareness of the trade-off and a concrete plan to address it. The classic example: shipping with a known architectural limitation in order to validate market fit, planning a refactor once the business case is confirmed.
How It Accumulates
- ●Deliberate architectural shortcuts with documented trade-offs
- ●Temporary data migrations using a simpler but less scalable approach
- ●Using a monolith structure until scale justifies microservices
- ●Skipping i18n on first launch when initial markets are English-only
- ●Manual deployment process while automation is being built
Consequences
- ▲Acceptable short-term: speed of delivery maintained
- ▲Risk if plan slips: debt accumulates without scheduled paydown
- ▲Team alignment required: everyone must know about the plan
- ▲Documented so future engineers understand the constraint
How to Address It
Create a formal record of every deliberate debt item: what was taken on, why, what the paydown plan is, and when it is scheduled. Use your sprint planning process to reserve capacity for debt paydown. Treat debt items like unfinished features on the backlog, not as things to be forgotten.
Inadvertent and Reckless
The most prevalent type in many codebases. Engineers do not know better practices exist and accumulate debt through well-intentioned but uninformed decisions. This is not a moral failure, it is an experience and knowledge gap. Early-stage startups often build their entire initial codebase in this mode.
How It Accumulates
- ●No separation of concerns in application structure
- ●Business logic mixed with presentation layer
- ●No consistent error handling patterns
- ●Database queries scattered throughout application code
- ●No understanding of thread safety or concurrency patterns
- ●No appreciation for SQL query performance until scale hits
Consequences
- ▲Difficult to test because code is tightly coupled
- ▲Bugs in one area cause unexpected failures elsewhere
- ▲Adding engineers does not increase throughput proportionally
- ▲Technical interviews become difficult because codebase is embarrassing
- ▲Often requires a complete rewrite rather than incremental refactoring
How to Address It
Invest in engineering education and mentorship. Senior engineers should run code review as a teaching practice, not just a gatekeeping function. Introduce linters, static analysis, and automated code quality tools to catch common patterns. Gradual refactoring using the strangler fig pattern can modernise the worst areas without a full rewrite.
Inadvertent and Prudent
The most forgivable type. A decision was made with the best available knowledge at the time. Later, through experience, reading, or team growth, better approaches are discovered. This is a normal part of software development and represents genuine learning.
How It Accumulates
- ●Following a tutorial that used an outdated pattern
- ●Choosing a library that later proved unsuitable for scale
- ●Building an API contract that does not accommodate future needs
- ●Using a data model that seemed correct but does not support evolved requirements
- ●Adopting a testing strategy that works at small scale but not large
Consequences
- ▲Relatively benign if caught early and addressed systematically
- ▲Can compound if discovered late in a large codebase
- ▲Usually addressable through targeted refactoring rather than rewrites
- ▲Often a trigger for valuable team discussions about better practices
How to Address It
Build a culture of regular retrospective code review. Architecture decision records (ADRs) help teams revisit past decisions in context. When better patterns are discovered, allocate time to update the codebase incrementally. This type of debt, properly managed, drives team learning and codebase improvement.