Technical debt at SMB scale: a triage framework.

Every codebase older than 18 months has accumulated debt. The question isn't whether you have it — it's whether you've named it.

Technical debt is one of those phrases that sounds like jargon and turns out to mean something specific and useful. The original metaphor, from Ward Cunningham, is right: it's the cost of every shortcut you took to ship faster. Like financial debt, you accumulate it intentionally, you pay interest on it weekly, and at some point the interest payments start crowding out the work you actually wanted to do.

The mistake most SMBs make is treating tech debt as binary — you either have a clean codebase or you don't — and as something the engineers complain about that leadership eventually has to "address" with a quarter of refactoring. Both framings are wrong. Tech debt is a spectrum, the engineers usually don't volunteer the worst pieces, and the right response is rarely a refactor.

Here's the framework that actually works at SMB scale.

Why most SMBs can't see their debt

The first problem is that the people closest to the code don't list it cleanly when asked. Engineers under-report debt because they live with it daily and have stopped noticing the parts that hurt most. They over-report debt in the parts they're currently frustrated by, which isn't the same thing as the parts that cost the company the most.

The second problem is that leadership doesn't have a vocabulary for it. "We have some technical debt" sits in a budget meeting next to "we should probably upgrade the CRM" — both are vague, both feel optional, and both get deferred indefinitely.

The third problem is that without a framework, the conversation defaults to the squeakiest wheel. The piece of debt that gets paid down is usually the one the loudest engineer cares about most, which has approximately zero correlation with the piece that's actually slowing the business down.

The interest-rate framing

The most useful question isn't "how much debt do we have?" It's "what's the interest rate on each piece of debt?"

Interest rate, in this context, means: how much does this piece of debt cost the team per week, in lost time or risk?

A 50,000-line legacy module that's stable, rarely modified, and well-isolated from the rest of the codebase is large debt at near-zero interest. You should leave it alone. A 2,000-line module that the team touches every week and that takes three days to make a one-day change in is small debt at very high interest. You should pay it down immediately.

This reframes the entire conversation. Instead of "should we refactor?" the question becomes "which piece is costing us the most per week?" That's answerable. That's prioritizable. That maps to a budget.

The companies that struggle most with tech debt aren't the ones with the most debt. They're the ones who haven't priced their debt — so every conversation starts at zero.

The four kinds of tech debt that hurt most

In SMB engagements, the same four patterns show up repeatedly. They're not the only kinds of debt, but they account for most of the weekly cost.

1. Integration debt

The team has built one-off connectors between systems that should be talking through clean APIs. Every change to one system requires manual changes in two or three places. The CRM, the ERP, the email system, the analytics pipeline — all connected by glue code nobody fully owns.

This is the highest-interest debt at SMB scale. It compounds with every new vendor added. The fix is rarely "rip and replace" — it's usually a thin abstraction layer that turns three brittle connections into one durable one.

2. Configuration debt

Production runs on settings that exist in someone's head. The deployment process requires "ask Mike" to complete. The credentials are in a shared document somewhere. Onboarding a new engineer takes two weeks because half the setup isn't written down.

Configuration debt looks small until Mike leaves. Then it's existential. The interest rate is invisible until the day it's catastrophic.

3. Test debt

The test suite covers the easy parts of the code. The parts you'd actually want to test — the integration points, the edge cases, the rare-but-expensive failure modes — are uncovered. So every change carries unknown risk and the team compensates by deploying slowly and reviewing carefully, which is the same thing as eating the interest.

The fix isn't to write tests for everything. It's to write tests for the high-risk paths that the team currently treats with kid gloves. Targeted coverage where it matters, not blanket coverage where it doesn't.

4. Vendor debt

The system relies on vendors that are either getting too expensive, too unreliable, or too embedded for comfort. The team knows the vendor needs to change. Nobody owns the migration. Every quarter, the price goes up and the dependency deepens.

Vendor debt is unique in that the interest rate compounds visibly — you watch it increase at every renewal. And yet it's the kind most often deferred, because the migration looks like a project and the renewal looks like a check to write.

A simple triage framework

For each piece of debt the team can name, ask three questions:

The answers produce a simple triage:

Most SMBs end up with three to five items in "pay down quarterly," one or two in "pay down now," and a long list in "monitor" or "ignore." That's a healthier picture than "we have a ton of tech debt" — it's a real plan.

When to pay down, when to refactor, when to leave alone

Three different responses, often confused with each other:

Pay down means small, surgical fixes that reduce the interest rate without rewriting the system. A configuration that lived in someone's head becomes a documented runbook. A flaky integration gets a retry layer. A risky deploy gets a rollback. Each fix takes hours to days, not weeks.

Refactor means restructuring code without changing behavior. This is appropriate occasionally — when a module is going to grow significantly, when a poorly-structured area is blocking new work, or when the test coverage is already in place to make it safe. Refactoring without one of those triggers is usually a vanity project.

Rewrite means starting over. Almost always wrong at SMB scale. The cost is enormous, the risk is high, and the new system will accumulate its own debt within 18 months. Rewrites make sense when the existing system genuinely cannot do what the business needs — not when it's just inelegant.

The default response should be "pay down." Refactor and rewrite are rarer. The trap is the engineer who wants to rewrite something they don't like, framed as a refactor, sold to leadership as paying down debt. All three are different things.

What good looks like at SMB scale

You're not aiming for a clean codebase. You're aiming for a codebase where the highest-interest debt is named, prioritized, and either being paid down or explicitly deferred — and where leadership knows what each piece is costing per week. That's a manageable system. The mistake is thinking the goal is zero debt. Zero debt is unreachable, and chasing it is itself a form of debt.

The companies that handle this well usually have a recurring quarterly conversation: "What's on the debt list, what moved up, what came down, what new debt did we take on, and what are we paying off this quarter?" Fifteen minutes per quarter, four times a year, run by someone with the experience to make the calls. That's the discipline. Everything else is downstream.

If you're trying to make sense of your codebase's debt and don't have an experienced voice in the room to triage it with, the free 30-minute discovery call is the right starting point. We'll walk through what you've got, name the highest-interest pieces, and tell you honestly whether the fix is structural or just a few small surgical pay-downs.

Got tech debt you can't quite name?

30 minutes, free, no pitch. We'll walk through what's on your team's mind, separate noise from real interest, and give you a triage you can actually use.

Book a Call →