An engineering manager explains technical debt to a new VP of Engineering: "Technical debt is the cost of prioritizing speed now over quality. Ward Cunningham coined the metaphor: writing quick, messy code is like borrowing money. You move fast, but you pay interest — slower feature development, more bugs, harder onboarding. The key insight is that not all debt is equal. Sometimes we deliberately take on debt — 'let's ship this MVP with a quick solution and refactor next quarter'. That's prudent. Other times debt accumulates because we didn't know better at the time. And sometimes it's just reckless: moving fast without any design, creating a mess that slows us down for years." According to Fowler's technical debt quadrant, what distinguishes prudent deliberate debt from reckless deliberate debt?
Fowler's Technical Debt Quadrant: two axes: Deliberate/Inadvertent and Reckless/Prudent. Four quadrants: Deliberate + Prudent: "We must ship now and deal with the consequences." Conscious trade-off. There is a plan. This can be good if you actually pay it back. Deliberate + Reckless: "We have no time for design." Ignores consequences. Often creates the worst long-term debt. Inadvertent + Prudent: "Now we know what we should have done." You learn through building — the design that seemed right turns out wrong. Normal part of software development. Inadvertent + Reckless: "What is layering?" Pure ignorance. The developer didn't know better practices existed. Technical debt metaphor vocabulary: Principal: the original quick solution (the code that exists now). Interest: the ongoing cost — slower feature development, more bugs, higher cognitive load every time someone touches the code. Paying off debt: refactoring. Compound interest: debt that's not paid accumulates — systems become increasingly hard to change, slowing all future work. Debt register vocabulary: Debt register: a tracked backlog of known technical debt items, each with: description, area of codebase, estimated effort to fix, estimated cost of not fixing (monthly developer hours), date introduced. Treats debt like a financial liability — visible to management, prioritized alongside features. In conversation: 'Deliberate prudent debt is a tool. We use it before every major release. The critical part is the "prudent" — we have a named ticket and a planned sprint to address it.'
2 / 10
A principal engineer explains the migration strategy to a team inheriting a legacy monolith: "We can't rewrite the system from scratch — that's too risky. The strangler fig pattern lets us migrate incrementally. We stand up the new microservices alongside the monolith. A proxy in front of the system routes traffic: new features go directly to microservices, old features still hit the monolith. As we migrate each domain to a microservice, we update the routing rules. Slowly, the new system 'strangles' the old one, just like a strangler fig tree grows around and eventually replaces the host tree. When the monolith handles zero traffic, we decommission it." What is the strangler fig pattern and why is it safer than a big-bang rewrite?
Strangler fig pattern (Martin Fowler, 2004): named after a tropical fig species that grows around a host tree. In software: the new system grows around the old one, gradually taking over its responsibilities until the original can be removed. Key elements: Façade/Proxy: a routing layer in front of both systems. In practice: API gateway, reverse proxy (NGINX), or feature flags. Incremental migration: one domain at a time. Ship to production after each migration. Parallel run: run both systems simultaneously during transition, comparing outputs to validate correctness. Traffic routing: start 1% → 10% → 100% for each migrated domain. Why big-bang rewrites fail: the new system must replicate all edge cases of the old system (which aren't documented). Development takes years. Business needs change during the rewrite. The team loses context as people leave. The "second system effect" — the rewrite is more complex than the original. Related patterns: Branch by abstraction: create an abstraction layer around the legacy code, then implement a new backend behind it, switch backends atomically. Works well for library/framework migrations. Parallel change (expand-contract): for API changes — add new format, migrate consumers, remove old format. Used for database schema migrations, API versioning. Event interception: use domain events emitted by the monolith to keep the new microservice in sync during migration. In conversation: 'No system has ever been successfully replaced by a big-bang rewrite on budget. The strangler fig is slower but it ships continuously and maintains stakeholder trust.'
3 / 10
A senior engineer explains code quality issues during a code review training: "Martin Fowler identified common code smells — patterns that indicate deeper problems. Long Method: a function that's 300 lines and does 10 different things. God Object: one class that knows everything and does everything. Feature Envy: a method that accesses data from another class more than its own — it belongs in that other class. Primitive Obsession: using raw strings and integers where you should have domain objects. Shotgun Surgery: making one change requires modifying 20 different files. Each smell is a hint that the design needs improvement. The remedy is refactoring — restructuring code without changing its observable behavior." What is a code smell and how does it differ from a bug?
Code smell: coined by Kent Beck, popularized by Martin Fowler in "Refactoring". Not a bug — the code may work perfectly. A smell indicates that the structure will make future changes harder. Common smells: Long Method: one method doing too many things. Remedy: extract method. Large Class (God Object): one class with too many responsibilities. Remedy: extract class, apply SRP. Feature Envy: method uses another class's data extensively. Remedy: move method. Data Clumps: same group of variables appear together repeatedly. Remedy: extract class. Primitive Obsession: using string/int where a domain class would be clearer. Remedy: replace primitive with object. Switch Statements: complex type-based branching. Remedy: polymorphism. Parallel Inheritance Hierarchies: adding a subclass in one hierarchy requires adding one in another. Lazy Class: a class that does too little to justify existence. Speculative Generality: over-engineering for hypothetical future use. Temporary Field: instance variable only used sometimes. Message Chains: a.b().c().d() — Law of Demeter violation. Inappropriate Intimacy: classes knowing too much about each other's internals. Refactoring vocabulary: Extract method: pull code out of a long method into a named function. Rename: clarify intent with better names. Move method/field: relocate to the class where it belongs. Inline: remove unnecessary indirection. Replace conditional with polymorphism: OO approach to complex branching. In conversation: 'A smell is a question mark, not a stop sign. It means: look here, there might be a better design. Sometimes the answer is: the smell is acceptable given our constraints.'
4 / 10
A tech lead explains how they communicate technical debt to non-technical stakeholders: "The metaphor that resonates most with executives is 'interest payments'. Every sprint, our team spends 20% of capacity dealing with debt — debugging unexpected interactions, working around bad abstractions, being afraid to touch fragile areas. That 20% is the interest we pay on the principal. If we invest one sprint per quarter in debt reduction — paying down the principal — we could drop that interest from 20% to 10%. The ROI is clear: one sprint of investment saves 3-4 sprints of drag per year. We track this in our debt register." What is the debt register and why is it more effective than a vague "tech debt backlog"?
Debt register: treats technical debt as a balance sheet liability, not a vague feeling. Fields per item: ID: unique identifier for tracking. Description: what is the debt? Location: which system/module/service? Type: design debt, test debt, infrastructure debt, documentation debt. Principal: cost to fix (story points / engineer-days). Interest rate: cost per sprint of NOT fixing (developer hours lost to workarounds, bugs caused). Total interest to date: principal × time accrued. Owner: team/engineer responsible. Priority: ROI = interest rate / principal. High ratio = high priority. Why vague backlogs fail: "tech debt" items compete with feature tickets on no objective basis. Engineers add items but nothing is ever prioritized. No one can answer "what is our total debt cost?" Presenting debt ROI to executives: "This authentication refactor costs 2 sprints to fix and saves 4 hours of engineer time per sprint. At fully loaded cost, it pays back in 12 sprints." This is the language executives understand. Technical debt metrics vocabulary: Cyclomatic complexity: number of independent paths through code. >10 is a warning. Cognitive complexity: SonarQube metric, weights nested branches more heavily. Coupling: how interconnected modules are. High coupling → changes cascade. Cohesion: how related a module's responsibilities are. Low cohesion → feature envy smells. Code churn: frequently modified files — high churn + high complexity = high bug risk. In conversation: 'When a debt register item shows it costs 3 hours/sprint in slowdown and 1 sprint to fix, the ROI calculation is elementary. The register makes prioritization a business decision, not an engineering argument.'
5 / 10
A platform engineer explains the deprecation process for an internal API: "We're sunsetting the v1 payments API in favor of v2. We can't just delete it — 8 internal services depend on it. The deprecation path: first, add a Deprecation response header to every v1 response with the sunset date. Send emails to teams. Give them 6 months. In month 3, make the v1 API log a warning when called with the calling service's name — gives us a visibility dashboard. In month 5, throttle v1 to increase pressure to migrate. On the sunset date, turn it off. The key is: no surprises, ample notice, and tooling to see who still needs to migrate." What is a deprecation path and what elements make it effective?
Deprecation path: the process of moving from "feature exists" to "feature removed" without breaking dependent systems. Key elements: Announcement: early, multi-channel (email, Slack, documentation). Include: what is deprecated, why, what replaces it, timeline. Machine-readable signals: HTTP Deprecation header (RFC 8594), Link header with sunset date. SDKs emit compiler warnings. Migration guide: how to move from old to new. Code examples. Usage visibility: logs, dashboards showing which teams are still using the deprecated feature. Without this, you can't know when it's safe to remove. Graduated pressure: warnings → throttling → removal. Sunset date: firm, published, enforced. Soft deadlines extend indefinitely. Escalation path: for teams that can't migrate in time (exceptions are rare and explicitly approved). API versioning vocabulary: Deprecation: the feature still works but is officially discouraged. Sunset: the date the feature stops working. Sunsetting: the process of removing the feature. Backward compatibility: old clients work with new API versions. Breaking change: a change that breaks existing clients. Semver: semantic versioning — major.minor.patch. Breaking changes bump major. Internal deprecation vs external: external (public API) requires longer notice periods and stricter SLAs. Internal deprecation can be faster if you have complete visibility into all consumers. In conversation: 'The "we'll remove it when everyone migrates" approach fails because there's always one team that waits until you force them. Set a date, stick to it, and make the date known from day one.'
6 / 10
Sarah (Senior Dev): 'Okay team, during this sprint we've been prioritizing getting feature X live. We're using a bit of hotfix code to achieve that, and I want to flag some potential technical debt. Specifically, the increased complexity in service_A.update() is concerning. What does it mean when I say we need to 'refactor this later?'
Refactoring doesn't imply immediate rewriting; it's about improving existing code without changing its external behavior. The goal is to reduce complexity and make the code easier to understand and maintain – a proactive approach to mitigating future problems. Choosing 'rewrite from scratch' is too risky and would likely introduce new issues.
7 / 10
Mark (Lead Architect) sends this message in Slack: 'Just FYI – the team's been using a workaround to bypass the rate limiting on the external API. It's technically debt because it's masking an underlying scalability issue and could lead to service degradation if the API provider changes their limits. We need to address this by…
The Slack message highlights a critical symptom: technical debt. The workaround isn't a fix; it's a band-aid masking a deeper problem. Addressing the root cause—the scalability issue—is essential for long-term stability and to prevent future issues when the API provider changes their limitations.
8 / 10
David (Code Reviewer) writes in a comment on a PR: 'This function is doing too much. It's handling input validation, data transformation, and logging all within one place. This violates the Single Responsibility Principle – it's a code smell. The fix needs to break this down into smaller, more manageable functions.' What does David mean by 'code smell'?
Code smells are not bugs themselves, but indicators of potential issues. Fowler's work identified these patterns – like overly long functions – as signals that deeper problems might exist in the design or implementation and warrant investigation.
9 / 10
Emily (Product Manager) is presenting to stakeholders: 'We're investing heavily in this new feature, but we've accumulated some technical debt over the past year. Think of it like interest payments on a loan – every sprint, we spend 15% of our time addressing these issues. If we don't pay down this debt now, it will significantly impact our ability to deliver future innovations.' What is Emily using as an analogy for technical debt?
Emily's using the 'interest payments' analogy to explain the long-term impact of neglecting technical debt. Just like loans accrue interest, delaying necessary improvements adds to the complexity and cost of future development – a crucial concept for non-technical stakeholders.
10 / 10
John (DevOps Engineer) writes in a PR description: 'We're implementing a phased deprecation of the old user authentication API. We'll gradually redirect traffic to the new API over a 3-month period, monitoring for errors and performance degradation along the way. This approach minimizes disruption while we migrate dependencies.' What does 'phased deprecation' refer to?
Phased deprecation is a controlled migration strategy. It's not about abruptly shutting down an API but instead transitioning users to a newer version incrementally – allowing for testing, monitoring, and graceful handling of any issues that arise during the transition.
What does the "Technical Debt Vocabulary" vocabulary exercise cover?
This exercise tests real IT vocabulary related to technical debt vocabulary through 10 multiple-choice questions, each built from realistic workplace sentences rather than abstract definitions.
Is this vocabulary exercise free to use?
Yes. Every exercise on CoderSlingo, including this one, is completely free — no account, sign-up, or payment required.
How many questions does this exercise have?
This exercise has 10 questions. Each one shows a real-world sentence or scenario with multiple-choice options and an explanation once you answer.
What happens after I answer a question?
You'll see immediate feedback showing whether your answer was correct, along with a short explanation of why — then a button to move to the next question, and a full results screen at the end.
Can I retry the exercise if I get questions wrong?
Yes. Once you reach the results screen, click "Try again" to reset your answers and go through the exercise from the start as many times as you like.
Do I need to create an account to take this exercise?
No account is needed. Your answers are scored in your browser during the session — nothing is saved to a server, so you can jump straight in.
Is my progress saved if I leave the page?
No — progress within an exercise resets if you navigate away or reload. Each exercise is short enough to complete in a few minutes in one sitting.
Are these vocabulary exercises connected to other topics?
Yes — browse the full vocabulary exercises hub to find related modules covering adjacent IT topics and roles.
How is this different from reading a glossary or blog article?
Exercises like this one are active recall drills — you have to choose the correct term or phrasing yourself, which builds retention faster than passively reading a definition.
Where can I find more vocabulary exercises?
Browse the full Vocabulary exercises hub for hundreds of modules covering Agile, DevOps, security, databases, architecture, and more — organised by IT role and skill.