skies.dev

Is Tech Debt a Bad Thing?

3 min read

Let me answer that question with another question: is financial debt always a bad thing?

Not necessarily. People use debt to buy time. A mortgage makes home ownership possible earlier than saving cash for decades. A business loan can fund equipment, payroll, or inventory before revenue catches up.

Tech debt works the same way.

Sometimes the right move is to ship the smaller, uglier version now:

  • a hard-coded config value to unblock a production fix
  • a temporary feature flag while a larger rollout is still being tested
  • a duplicated integration path so a customer bug can be patched without waiting on a full refactor
  • a simplified data model so a launch date does not slip by two quarters

Those choices are not ideal. They are tradeoffs. The mistake is pretending they are free.

Every time we take on tech debt, we are borrowing against future engineering time. The bill usually shows up later in one of three places:

  • slower delivery, because every change needs extra caution
  • more bugs, because the code is harder to reason about
  • higher operational risk, because the workaround becomes part of the critical path

The practical question is not "did we create tech debt?" The practical question is "did we create debt on purpose, and do we know how we are going to pay it back?"

That means being explicit.

If you add a shortcut, write down:

  1. what was skipped
  2. why it was acceptable at the time
  3. what symptom will tell you it is time to fix it
  4. who owns the cleanup

For example, "We are parsing the legacy webhook payload in place for the launch next week. Once traffic is stable, we need to move this into a typed adapter because the current code cannot support a second provider without branching everywhere."

That is a manageable debt. It has a scope, an owner, and a trigger for repayment.

Bad tech debt looks different.

  • nobody remembers why the workaround exists
  • the code has been copied into three places
  • the team is afraid to touch it, so small changes require big deploys
  • every incident postmortem ends with "this area is fragile" and nothing changes

At that point, the debt is no longer helping you move faster. It is slowing the system down.

The fix is not a heroic rewrite. Most of the time, repayment works best in small slices:

  • remove one special case
  • delete one duplicate path
  • add one test around the risky behavior before changing it
  • move one piece of logic behind a stable interface

If you try to pay down everything at once, you usually get a second problem: a long-lived refactor that blocks feature work and never ships.

My rule is simple:

  • take debt when it buys real speed or reduces real risk
  • record why it exists
  • keep the scope small
  • schedule repayment before the workaround turns into architecture

Tech debt is not failure. It is a cost of shipping software under constraints. The failure is letting a temporary decision become permanent without ever deciding to keep it.

Hey, you! 🫵

Did you know I created a YouTube channel? I'll be putting out a lot of new content on web development and software engineering so make sure to subscribe.

(clap if you liked the article)

You might also like