"We'll Fix It Later" Is the Most Expensive Sentence in Software
Photo: developer refactoring legacy code multiple monitors dark office, via thumbs.dreamstime.com
Every founder has said it. Every developer has heard it. "We'll fix it later."
Here's the uncomfortable truth: later never comes with a reasonable price tag. Later comes when you're mid-fundraise, when your biggest enterprise client is threatening to churn, or when your lead engineer quits and takes the only mental map of your spaghetti codebase with them to a competitor.
At Bad Boy Software, we've inherited enough haunted codebases to know the pattern. So let's talk about debt — the kind that doesn't show up on your balance sheet until it's eating your roadmap alive.
Debt Isn't the Problem. Denial Is.
Let's get one thing straight: tech debt is not a moral failing. Shipping fast and cutting corners is sometimes the right call. If you're racing to validate a product idea, elegant architecture is a luxury you can't afford. Debt taken on deliberately to hit a market window is a tool, not a sin.
The problem is the debt nobody chose. The debt that accreted silently because nobody tracked it, nobody priced it, and nobody was accountable for it. That's the debt that turns your two-week feature into a two-month ordeal.
If your team's velocity has quietly halved over the past year and nobody can say why, congratulations — you're not shipping features anymore. You're servicing debt.
The Three Questions Before You Touch Anything
Before you schedule a single refactor sprint, run your problem code through this filter:
1. Is this code on a hot path? Debt in your billing system, your auth flow, or your checkout page compounds daily because every user touches it. Debt in that admin dashboard only your ops intern opens? Let it ride. Ruthless refactoring means triaging by blast radius, not by how ugly the code looks.
2. Is the code still changing? Stable code that works is not debt — it's an asset, however hideous. Refactoring code that never changes is interior decorating. If a module gets modified every sprint, that's where debt taxes you hardest, because every change pays the interest again.
3. Do you understand what it does? This is the scary one. If nobody on your team can confidently explain what a piece of code does, refactoring it is a gamble and rewriting it is a coin flip. Untested, undocumented, misunderstood code is the only category where "rewrite from scratch" is genuinely on the table.
Patch, Pay Down, or Rebuild: A Founder's Decision Framework
Here's how we'd call it:
- Patch it when the debt is contained, the code is tested, and you have a live fire to put out. Ship the fix, log the debt, move on. Speed wins.
- Pay it down when the code is on a hot path and actively evolving. Budget 15–20% of each sprint for refactoring as you go. Not a quarterly "cleanup week" — those are theater. Debt gets paid in small, continuous installments or not at all.
- Rebuild when all three questions above come back bad: hot path, changing constantly, and nobody understands it. Yes, this is rare. Most "we need a full rewrite" moments are actually fatigue talking. But when a system is a genuine liability — security holes, data integrity risks, a framework so dead it's a hiring problem — stopping the bleeding beats patching the wound.
One rule for rebuilds: never do a big-bang rewrite. Rebuild strangler-style, module by module, with the old and new systems running side by side. Anyone who proposes a six-month rewrite with zero shippable output in between is selling you a bridge.
Budgeting Debt Paydown Without Killing Your Roadmap
Founders fear refactoring because it sounds like paying engineers to not build things. Fair. So make the trade explicit:
Cap it at 20%, no negotiation. Every sprint, one in five engineering days goes to debt. When a big release ships, temporarily bump it to 30% for a couple of sprints to clean up the shortcuts you knowingly took. Then drop back down.
Tie debt work to features. The best refactoring doesn't happen in isolation — it happens when you touch a module to build something new and leave it better than you found it. Boy Scout rule, enforced by habit, not memos.
Track debt like a metric. If you can't see it, you can't budget it. A simple debt register — what it is, where it lives, what it's costing you in slowed delivery — turns vague anxiety into a line item. Line items get funded. Vibes don't.
Kill Code Without Ceremony
Here's the most underrated refactoring move in the business: deletion. Dead features, commented-out blocks, that experimental module from 2022 — every line of dead code is a tax on comprehension for every future engineer who reads it.
You have version control. Nothing is ever really gone. Delete aggressively, and delete often.
The Bottom Line
Tech debt doesn't respond to negotiation, guilt, or annual planning retreats. It responds to triage, budgeting, and a bias toward action. The shops that win aren't the ones with zero debt — they're the ones who know exactly what they owe, who they owe it to, and when the payment is due.
Stop treating your codebase like a junk drawer. Start treating it like the balance sheet item it is.
And if you've inherited a codebase that answers all three questions wrong? That's what we're here for. No judgment, no 40-page audit deck. Just a plan.