Glossary
By the Glue Team
Technical debt is the accumulated cost of shortcuts, quick fixes, and suboptimal decisions made during software development. Like financial debt, technical debt has interest—it gets more expensive to pay back the longer you ignore it. Code with high technical debt becomes increasingly difficult and risky to modify.
Technical debt metaphorically applies financial debt concepts to code. When you incur debt, you gain something now (quick delivery, fewer features) but pay interest later (slower development, bugs, maintenance burden).
Technical debt includes:
Quick fixes that skip proper design: Hardcoding values instead of making them configurable. Using global state instead of passing parameters. Duplicating code instead of extracting functions.
Deferred refactoring: Code that works but is hard to understand. Functions that do too many things. Module boundaries that don't make sense.
Missing tests: Code that has no automated tests. Features that can't be refactored safely because there's nothing to catch regressions.
Poor documentation: Undocumented decisions. APIs with no usage examples. Systems no one remembers how to deploy.
Outdated dependencies: Libraries that are no longer maintained. Frameworks two versions behind. Dependencies with known security vulnerabilities.
Architecture decisions that didn't age well: Monolithic architecture that should be microservices. Synchronous systems that should be asynchronous. Choices made for valid reasons that are no longer valid.
Technical debt directly impacts development speed, reliability, and cost:
Slows Development Over Time: Technical debt compounds. Each new feature built on top of a shaky foundation becomes riskier. More testing is needed. More edge cases emerge. Estimates become less accurate because no one knows what will break.
Studies show that teams with high technical debt spend 23-42% of development time on debt-related work instead of new features. This isn't just slower—it's what causes projects to miss deadlines and scope to creep.
Increases Bug Rates: Code with high debt is fragile. Changes in one place break things in unexpected places. Testing is hard because everything is interdependent. Production incidents increase.
Makes Changes Risky: Refactoring becomes dangerous when there are no tests. Migrating to new technologies becomes impossible when code is tightly coupled. You become locked into suboptimal decisions.
Creates Knowledge Silos: Undocumented code becomes tribal knowledge. The person who wrote it understands it; everyone else is lost. That person becomes irreplaceable. When they leave, knowledge leaves with them.
Impacts Hiring and Retention: Developers hate working in high-debt codebases. Every change is stressful. Every deployment is scary. This causes burnout and turnover, ironically in the places that most need stability.
Interest Compounds: Early debt is cheap to pay back. The original author remembers why they made the shortcut. Code is still recent. But as debt ages, paying it back costs more. The original author has left. Code is intertwined with other systems. Refactoring becomes complex.
Technical debt manifests in different ways:
Code Debt: Poorly structured code, duplicate logic, complex functions. Quick to incur, relatively quick to pay back through refactoring.
Architectural Debt: Wrong architectural decisions that seemed right at the time. Monolithic architecture that should split into services. Synchronous systems that should be asynchronous. Expensive to pay back because it affects everything.
Documentation Debt: Missing documentation. Undocumented decisions. APIs without clear contracts. Hard to measure but expensive because it affects onboarding and decision-making.
Testing Debt: Low test coverage. Untested edge cases. Manual testing instead of automation. Can be paid back but creates risk while debt exists.
Dependency Debt: Outdated frameworks. Libraries that are no longer maintained. Dependencies with security vulnerabilities. Paying back requires compatibility testing.
Organizational Debt: Unclear processes. Poor communication structures. Decisions made without context. Less tangible but equally expensive.
The goal isn't to eliminate all debt—some is inevitable and sensible. The goal is to manage it:
Track It: You can't manage what you don't measure. Identify your highest-debt areas. Quantify them (complexity metrics, test coverage, deployment frequency). Review quarterly.
Communicate It: Make technical debt visible to leadership. When a feature takes two weeks instead of one because of debt paydown, say so. Help non-technical stakeholders understand that debt is a cost.
Allocate Time: Reserve time for debt paydown. 20% of sprint capacity is a common allocation. Without dedicated time, debt compounds forever.
Prioritize: Not all debt is equal. Debt in frequently-changing code is worse than debt in stable code. Debt that blocks new features is worse than debt that doesn't. Focus on high-impact debt first.
Prevent New Debt: The best debt management is prevention. Establish standards. Code reviews. Testing requirements. Making the right way easier than the shortcut.
Refactor Systematically: Don't try to refactor everything at once. Make small improvements continuously. Refactor when touching code anyway. This keeps debt from growing while gradually improving it.
Glue helps manage technical debt by visualizing where it's concentrated, identifying complexity hotspots, and tracking improvements over time. When your team understands where technical debt lives, you can make informed decisions about what to prioritize.
"We should never incur technical debt." False. Some debt is sensible. Launching early with some shortcuts might make business sense. The issue is not managing it afterward.
"Technical debt is about writing bad code." Partly false. Sometimes the best engineers deliberately incur debt (understanding the trade-offs) to ship faster for competitive reasons. Debt becomes a problem when ignored or untracked.
"We can pay off all our debt." False. Codebases always have some debt. The goal isn't zero debt; it's managed debt that doesn't compound faster than you can pay it back.
"Refactoring pays off technical debt." Partly true. Refactoring helps, but only if you're also adding tests, documenting decisions, and updating dependencies. Refactoring code that has no tests just creates different debt.
Code Health: Overall quality of the codebase. High technical debt means poor code health.
Code Complexity: One dimension of technical debt. Complex code is harder to maintain.
Code Coverage: Another dimension. Untested code is technical debt waiting to cause problems.
Developer Onboarding: Technical debt affects onboarding speed. High-debt codebases slow down new developers.
Q: How do you measure technical debt? A: Multiple approaches. Quantitative: test coverage percentage, cyclomatic complexity, dependency age, code duplication percentage. Qualitative: code review feedback, deployment frequency, time to add features. Combine metrics to get a sense of overall debt.
Q: Should product managers care about technical debt? A: Yes. Technical debt directly impacts velocity. A product manager who ignores technical debt will find their roadmap increasingly at risk. Features take longer. Quality suffers. The team burns out. Understanding technical debt helps PMs make better trade-off decisions.
Q: Can technical debt be paid back too quickly? A: Yes. If you allocate too much time to debt payback and never ship features, the business suffers and team morale drops. The balance should prioritize business value while allocating sufficient time to keep debt manageable.
Keep reading