Technical debt vs. new features: how to set priorities
Source: Dev.to
The Conflict
- Engineering – A legacy service is getting slower and harder to deploy.
- Product – A new feature, backed by customer requests and a clear business case, is pushing for priority.
This creates the classic tension in software development: technical debt vs. new functionality.
Current Situation
- Decisions often rely on gut feelings rather than data.
- Urgent features repeatedly win, leaving the underlying problems to fester.
- The “kick‑the‑can‑down‑the‑road” approach accumulates hidden costs.
Symptoms
| Symptom | Description |
|---|---|
| Gradual slowdown | Build times creep upward; simple changes now touch dozens of files. |
| Risk‑averse behavior | The team starts avoiding certain code areas because any tweak feels risky. |
| Environment friction | Setting up a local environment can take an entire day. |
| Flaky test suites | Debugging unstable tests becomes a regular time sink. |
Impact on Morale
- Frustration – No one enjoys spending a full day on environment setup or chasing flaky tests.
- Productivity loss – The friction acts as a tax on every feature the team tries to build.
- Operational risk – Each deployment carries higher chances of failure because the codebase is fragile.
Takeaway
The ongoing battle between fixing technical debt and delivering new features is eroding speed, increasing risk, and hurting team morale. A more data‑driven, balanced approach is needed to break the cycle.
Reframing Technical Debt: Not All Debt Is Equal
The term technical debt is often too broad. It lumps together a quick workaround you knowingly implemented to hit a deadline with a critical piece of architecture that has slowly decayed over five years.
To make better decisions we must first separate these two kinds of debt. Treating everything as a single monolithic problem is why we fail to address it systematically.
Understanding the Nature of Your Technical Debt
A more useful way to think about debt is to categorize it. Was the debt intentional or emergent?
| Type | Description | Typical Origin | Risks |
|---|---|---|---|
| Intentional debt | A conscious trade‑off made to meet a short‑term goal. | Skipping comprehensive tests for a pilot, using a simpler data model for an MVP, etc. | Becomes a problem only if the “plan to address it later” never materializes. |
| Emergent debt | Unplanned decay that accumulates as the system evolves. | Multiple teams contributing code, shifting requirements, architectural patterns that made sense two years ago but are now bottlenecks. | Harder to define, often has no clear owner, and can silently erode system stability. |
Key takeaway:
Differentiating between an acceptable compromise and critical architectural decay is the first step.
- Intentional debt → schedule a known remediation task.
- Emergent debt → launch a discovery project to understand scope and ownership.
Beyond Gut Feelings: The Need for Deliberate Decisions
Without a clear framework, prioritization devolves into a battle of opinions:
- Engineers: “The system is hard to work with.”
- Product managers: “Revenue projection looks great.”
When decisions are made ad‑hoc, the loudest voice or the most immediate deadline usually wins. This leads to multi‑quarter “modernize the platform” projects that only get approved after a major outage, rather than making small, consistent investments over time.
A consistent decision‑making framework shifts the conversation from feelings to impact:
- Define impact metrics (e.g., mean‑time‑to‑recover, deployment frequency, defect leakage).
- Quantify trade‑offs (cost of building a feature vs. cost of ignoring the problem).
- Use a shared language with non‑technical stakeholders (e.g., “technical debt cost per sprint”).
By making the true cost of both building a feature and ignoring a problem visible to everyone, you ensure long‑term system health isn’t constantly sacrificed for short‑term gains.
A Clearer Way to Define Priorities
A good framework forces you to evaluate both technical debt and new features using the same criteria: impact, cost, and risk. Instead of comparing apples and oranges, you assess both types of work based on how they affect the business, the customer, and the team.
Assessing the Impact of Technical Debt
To make a case for fixing something, you need to articulate its specific, measurable impact. Engineers often fall short by using vague terms like “code quality” or “maintainability.” Focus on quantifying the pain in three areas:
| # | Area | What to Ask | Example |
|---|---|---|---|
| 1 | Operational Risk | How likely is this to cause an incident? Does it affect system stability, security, or performance? | “This unindexed query spikes database load and has triggered P2 alerts twice in the last month. It’s only a matter of time before it causes a major outage.” |
| 2 | Developer Friction | How much time is being wasted? Measure developer velocity (slow builds, complex local setup, flaky‑test debugging). | “The CI pipeline for this service takes 45 minutes. With five developers, we lose >10 hours of productive time per week waiting for builds.” |
| 3 | Future Blockers | Does this debt prevent or slow down future feature development? | “We can’t build the new reporting feature because the current data model doesn’t support the required aggregations; we must refactor it first.” |
Evaluating New‑Feature Value
New features also need scrutiny beyond the initial pitch. Every feature has an opportunity cost, so it’s important to understand the real value it delivers. The goal isn’t to block features, but to have a clear‑eyed view of what you’re prioritizing.
| Dimension | Questions to Consider | What to Look For |
|---|---|---|
| Business Value | What is the expected outcome? Is it tied to revenue, user acquisition, or retention? Are the numbers based on solid data or speculation? | A feature projected to increase revenue by 10 % vs. a “nice‑to‑have” for a small user subset. |
| Strategic Alignment | How does this fit the core product vision? Is it a key differentiator or a distraction? | Features built to close a single deal that pull the product away from its long‑term direction. |
| Cost of Delay | What happens if we ship this next quarter instead of this one? Does a delay miss a market window or seasonal event? | Some features lose relevance quickly; others can wait without impact. |
Quick Checklist for Prioritization
- Identify the impact area (operational risk, developer friction, future blocker).
- Quantify the impact (e.g., incident frequency, hours lost, blocked features).
- Map the feature to business value, strategic fit, and cost of delay.
- Compare the quantified debt impact against the projected feature value.
- Make a decision based on the net benefit to the business, customers, and the team.
Using this structured approach ensures that both technical debt and new features are judged on a common, transparent set of criteria.
The Prioritization Matrix: Balancing Risk and Reward
Once you’ve assessed both sides, you can start making decisions. You don’t need a complex spreadsheet—a simple mental model or a whiteboard session can help visualize the priorities. Think of it as a 2 × 2 matrix where one axis is “Impact / Value” and the other is “Effort / Complexity.”
Plotting Debt and Features for Decision‑Making
When you plot the items, you can establish clear criteria for what to do with them.
- A piece of technical debt that is high‑risk and blocks new features should be treated with the same urgency as a high‑value feature.
- A low‑friction piece of debt that isn’t causing immediate harm can probably be deferred.
This process helps you define three clear categories of work:
| Category | Description | When to Use |
|---|---|---|
| Fix Now | High operational risk, significant developer friction, or a blocker for an upcoming critical feature. | Equivalent to a production incident waiting to happen. |
| Schedule | Important but not on fire. Could be a refactoring project that would significantly improve developer velocity, or a feature with a clear business case but no hard deadline. | Explicitly schedule into an upcoming sprint or quarter. |
| Defer | Low impact, low risk. Messy‑but‑functional code that developers complain about but that doesn’t actually slow anyone down or pose a real threat. | Acknowledge the issue but agree not to work on it now. |
Integrating Prioritization into Your Development Cycle
This framework can’t be a one‑off exercise; it needs to be part of your team’s regular operating rhythm.
- Allocate time in planning – e.g., dedicate 20 % of each sprint to scheduled technical improvements.
- Empower teams to manage their local technical debt proactively, allowing them to fix small issues as they encounter them without needing separate approval for every refactor.
- Make discussions transparent and involve product and business stakeholders.
When you can explain that fixing a slow database query will unblock three upcoming features and reduce the risk of outages, the conversation shifts from “engineers wanting to refactor” to “making a smart investment in the future of the product.”