Direct answer
I chose neither extreme. Technical debt is the accumulated cost of earlier shortcuts in code, which makes every later change slower and riskier. A refactor is restructuring existing code, without changing what it does, so it is easier and safer to change. I did a short, targeted refactor of only the code the new feature had to touch, then built the feature on it, and logged the rest of the debt with an owner and a date. I explained the trade to the PM in terms of mispriced orders and launch risk, not code quality. The story uses illustrative numbers; use your own when you tell it.
Context
Product wanted a promo-code feature to be live for a seasonal campaign in 5 weeks. It had to live inside the pricing service, a large, untested function where small changes often produced pricing bugs.
Worked example: the options and their timelines
| Option | Plan | Weeks | Issue |
|---|
| A. Build on existing code | Feature only | 3 | Fastest, but the discount path is the part of the code that fails most |
| B. Full refactor, then feature | 3 + 2.5 | 5.5 | Misses the 5-week date |
| C. Targeted refactor, then feature | 1 + 2.5 | 3.5 | Half a week slower than A, 1.5 weeks of buffer inside the date |
How I assessed the trade-offs
I pulled the previous quarter's bug tickets: 9 of the 14 pricing bugs (about 64%) were in the discount code path, the exact area the feature would change. That data, not my feelings about the code, made the case. A had the lowest cost and the highest chance of mispricing during the campaign; B was safe but late; C bought tests around the one area we were about to change for half a week more than A.
Communication
- PM: "Half a week buys confidence that campaign discounts will not misprice orders, and we still launch with a week and a half of buffer."
- My manager: asked for the first week to be protected from other requests.
- Peers: agreed a review plan for the extracted code so the knowledge spread.
Decision and outcome
I took C. The campaign launched on time. Over the next quarter, pricing bugs fell from 9 in the discount path to 3 (illustrative), and the remaining refactor sat in a dated ticket with an owner rather than in my head.
Other situations where business value competes with technical debt
- A model shipped with a manual step: ship the model now with a feature script that someone runs by hand (the script that turns raw data into the inputs the model reads), but log the cost it adds. Illustrative numbers: 6 hours of manual retraining each month is 72 hours a year, about 1.8 engineer-weeks at 40 hours. Track both sides, the near-term business metric and that long-term cost, and review them next quarter.
- Making the case for a refactor to someone who wants a revenue feature: make the case in lead time (the elapsed days from starting a change to it being live), not neatness. Show how long the last three changes in that area took compared with similar changes elsewhere, and propose folding the refactor into the feature.
- Quality already compromised to hit a deadline: write down what was skipped, create a dated ticket with an owner, and schedule remediation before the next deadline, or it never happens.
- Platform work (shared infrastructure that other teams build on) deliberately postponed for a strategic opportunity: say what was postponed, until when, and which signal would reopen the decision. Example: "We postpone the deploy-pipeline upgrade to ship the partner integration. If deploys exceed 30 minutes or the share of failed deploys passes 10% (illustrative), we reopen the decision."
- A scaling problem versus user-facing work: use data. For example, if a database is at 60% of its connection limit and grows 5 points a month, the limit arrives in (100 - 60) / 5 = 8 months. Compare that with the cost of delaying the user-facing work, and track p95 latency (the time within which 95% of requests finish) and error rate (the share of requests that fail) against the traffic forecast: for example, if the forecast says traffic doubles in six months, check whether p95 latency stays under the agreed limit at double the load.
Trade-offs and pitfalls
- A refactor with no stated business reason sounds like a preference.
- Compromised quality without a dated remediation plan becomes permanent debt.