DEV Community

Cover image for Technical Debt Is a Myth Created By Bad Managers
Adam - The Developer
Adam - The Developer

Posted on

Technical Debt Is a Myth Created By Bad Managers

Hot take incoming. Buckle up.


I've spent quite some time writing about technical debt, preaching clean code practices, and advocating for sound architecture. I've told developers how to avoid it, how to pay it down, how to negotiate it with their managers.

Here's the thing: I was partially wrong.

Not about the practices—those are still good. Not even about all uses of the term. But about accepting the framework uncritically.

Technical debt isn't just misunderstood; it's a fundamentally broken metaphor that's warping how we think about software development. And the worst part? We keep using it because it's the only financial metaphor executives understand, which means we're stuck explaining engineering problems in terms that actively obscure what's actually happening.

Let me explain.

Table of Contents


⁉️ The Problem with the Metaphor

Ward Cunningham coined the term "technical debt" in 1992 to describe a specific scenario: deliberately choosing a quick implementation with the understanding that you'd refactor it later. Like financial debt, you're borrowing time now with the promise to pay it back with interest.

But here's what actually happens in most organizations:

Manager: "Why is this feature taking so long? I thought you said it'd be done in two weeks?"

Engineer: "Well, we have a lot of technical debt to work around..."

Manager: "Ugh, why didn't you guys write better code in the first place?"

And just like that, the engineers are the bad guys. The ones who "accrued debt." The ones who took "shortcuts." The ones who are now holding the company back.

Except that's complete garbage.

🗳 Debt Implies You Had a Choice

Real debt works like this: you go to a lender, negotiate terms, sign papers, and agree to pay back the principal plus interest. You understand the deal. You consent to it.

Technical debt? Here's how that actually happens:

Manager: "We need this shipped by Friday for the investor demo."

Engineer: "That's not enough time to do it properly. We'd need at least three weeks to build it right."

Manager: "Make it work. I don't care how."

[Three months later]

Manager: "This codebase is a mess."

See the problem? The engineer didn't "borrow" anything. They didn't choose debt. They were given impossible constraints and did the best they could. And now they're being blamed for the "interest."

This isn't technical debt. It's the technical consequences of management's decisions.

🗿 All Code Ages (That's Not Debt, That's Entropy)

Here's another thing that drives me crazy: calling any older code "technical debt."

Your 4-year-old codebase that uses React 16 instead of the latest version isn't "debt." Your API that returns XML instead of GraphQL isn't "debt." Your monolith that everyone now wishes was microservices isn't "debt."

That's just code that exists in time.

Requirements change. Platforms evolve. Best practices shift. New frameworks emerge. The context in which your code was written is not the context it lives in today.

Calling this "debt" implies someone made a mistake. It implies negligence. It implies that if only the engineers had been smarter, more forward-thinking, more competent, this wouldn't be a problem.

But that's not how software works. That's not how anything works. You can't predict the future. You can't build for requirements that don't exist yet. And even if you could, you'd be over-engineering and wasting time building flexibility you'll never use.

🛎 The "Debt" Was Usually the Right Call

Let's talk about that MVP you built two years ago. The one that's now "legacy." The one that "needs to be rewritten." The one that's "holding you back."

You know what else that MVP did? It validated your business model. It acquired your first thousand users. It generated the revenue that lets you have this conversation.

Without that "bad code," you'd have nothing. You'd have gone out of business waiting for the "perfect architecture."

But now that it's successful, now that it's scaling, now that you want to move faster... suddenly it's "technical debt." Suddenly the engineers who built the thing that made your company viable are being blamed for not having built it "right."

This is survivorship bias and hindsight bias rolled into one toxic burrito.

💳 What Managers Call "Debt," Engineers Call "Trade-offs"

Every single engineering decision is a trade-off. Not some of them. Not most of them. All of them.

  • Speed vs. flexibility
  • Simplicity vs. features
  • Proven technology vs. cutting edge
  • Build vs. buy
  • Monolith vs. microservices
  • SQL vs. NoSQL
  • Testing coverage vs. shipping speed

There is no "right" answer to any of these. There's only "right for our current context, constraints, and priorities."

Good managers understand this. They participate in these decisions. They say things like:

"We're optimizing for speed right now because we need to validate the market. We'll revisit the architecture once we have product-market fit."

Bad managers say:

"Just make it work. Figure it out."

And then later:

"Why is there so much technical debt?"

🙈 The Real Problem: Compounding Ignorance

Here's what actually happens when managers don't understand the compounding nature of maintenance costs:

Year 1: "Ship fast! Don't worry about perfect code!"

Year 2: "Why are new features taking longer? We used to ship so quickly!"

Year 3: "We need to stop all feature work and do a rewrite."

This isn't technical debt. This is management not understanding that software maintenance is not free. That every feature adds surface area. That every dependency needs updating. That every API needs versioning.

The engineers knew this. They told you. You didn't listen because you were focused on the next quarter.

➖ Okay, But What About Actual Shortcuts?

Fine. Yes. Sometimes engineers do genuinely cut corners. We skip writing tests. We hard-code values. We don't handle errors properly. We copy-paste instead of abstracting.

But you know what? That almost always happens because of external pressure.

"We need this for the demo tomorrow."

"The client is threatening to leave if we don't ship this week."

"We're hemorrhaging cash and need revenue now."

Even the genuinely bad engineering decisions are usually made under duress, with limited time, incomplete information, and immense pressure from... wait for it... management.

🔧 The Uncomfortable Truth: Sometimes It Really Is Bad Engineering

Alright, let's be honest here. I can't write a whole post defending engineers without acknowledging the elephant in the room: sometimes the code really is just bad, and it's not management's fault.

Sometimes you hire a developer who:

  • Doesn't understand the language or framework they're using
  • Copies Stack Overflow answers without understanding them
  • Writes nested conditionals twelve levels deep because they never learned about early returns
  • Creates God classes with 5,000 lines because "it's easier to keep everything in one place"
  • Refuses to learn or grow because "this is how I've always done it"

And sometimes, your code review process is so broken that this stuff gets into production anyway.

The Code Review That Rubber Stamps Everything

You know this pattern. Someone opens a PR at 4:45pm on Friday. It's 847 lines of changes across 23 files. The reviewer glances at it for 90 seconds, sees no obvious syntax errors, and hits "Approve" so they can start their weekend.

Or worse, you have a "senior" engineer who's territorial and defensive, and everyone's afraid to give real feedback because last time someone suggested a refactor, they got a 2,000-word essay about why they're wrong followed by three weeks of passive-aggressive Slack messages.

When the Team Has No Standards

Some teams genuinely have no coding standards. No style guide. No architectural principles. No agreed-upon patterns. Everyone just does whatever feels right to them in the moment.

One person writes functional code with immutable data structures. Another writes OOP with heavy inheritance. A third person discovered dependency injection last week and is now injecting everything including the kitchen sink. The fourth person just wants to ship and doesn't care about any of this.

The result? A Frankenstein codebase where every module feels like it was written by a different company.

The Junior Developer Left Unsupervised

Here's a scenario that's more common than we'd like to admit: you hire a junior developer, give them a ticket, and... nobody checks in on them. They struggle for two weeks, eventually get something working through trial and error, and ship it. It works (mostly), so it goes to production.

Six months later, someone has to modify that code and discovers it's holding together with duct tape and prayers. No tests. No error handling. Variables named temp1, temp2, finalFinal, finalFinalActual. Business logic mixed with UI code mixed with database queries.

Is that technical debt? Is that management's fault? Kind of yes, kind of no.

Management failed to provide mentorship and oversight. But also, the engineer could have asked for help. Could have looked at existing code for patterns. Could have... you know, tried.

💬 The Nuance Nobody Wants to Talk About

So here's where it gets complicated. Because even when the code is genuinely bad due to engineering failures, the "technical debt" framing is still wrong.

Why? Because calling it "debt" still:

  • Frames it as an intentional trade-off (it wasn't)
  • Implies it should be "paid back" (it should be fixed)
  • Obscures the root cause (hiring, training, code review, or standards problems)

If you hired someone who's not good enough, that's a hiring problem. If your code reviews aren't catching issues, that's a process problem. If your team has no standards, that's a leadership problem. If juniors are shipping unmaintainable code, that's a mentorship problem.

None of these are "debt." They're organizational failures that manifest as code quality issues.

And here's the kicker: even these failures often trace back to management decisions. Who decided to:

  • Hire the cheapest developers instead of the best ones?
  • Skip the technical portion of the interview because the candidate "seemed smart"?
  • Not allocate senior engineer time for code reviews and mentorship?
  • Never invest in establishing team standards or architectural guidelines?
  • Prioritize story points over code quality?

See how we keep ending up back at management?

™️ When Engineers Need to Own It

But let's not let ourselves completely off the hook. As engineers, we need to own our craft. We need to:

  • Actually review code, not just rubber-stamp it
  • Give and receive feedback like professionals
  • Invest in learning and growth
  • Ask for help when we're stuck
  • Push back on terrible code in PRs, even if it's uncomfortable
  • Establish and maintain standards as a team

If you approved a PR without reading it, you share responsibility for that code. If you wrote sloppy code because you couldn't be bothered to care, that's on you. If you've been writing the same bad patterns for five years and refuse to learn, you're the problem.

The difference? When we own these failures, we can actually fix them. We can improve our code review culture. We can level up our skills. We can establish better practices.

But when we hide behind "technical debt" as a vague catch-all, we can't fix anything because we're not even identifying the real problem.

So What Should We Call It Instead?

Instead of "technical debt," try these:

"Technical consequences of past business decisions" - Wordy, but accurate. Keeps the accountability where it belongs.

"Maintenance cost" - Every codebase has one. It grows over time. Budget for it.

"Context shift" - What made sense two years ago doesn't make sense now. That's okay.

"Necessary refactoring" - Software evolves. Refactoring is normal. Stop treating it like a punishment.

"The cost of learning" - You didn't know what you were building would be successful. Now you do. Time to optimize.

🔚 The Bottom Line

Technical debt isn't a myth because shortcuts don't exist. It's a myth because the metaphor has been corrupted beyond recognition.

It's become a way for managers to:

  • Blame engineers for business decisions
  • Avoid accountability for resource allocation
  • Treat normal software evolution as negligence
  • Escape responsibility for impossible deadlines

Good managers own the trade-offs. They say "We chose speed over flexibility and now we need to re-optimize. That'll take time and resources. I'm allocating both."

Bad managers weaponize hindsight. They say "You should have built it right the first time. Why is there so much technical debt?"

If you're a manager reading this and you've ever complained about technical debt, ask yourself: did you give your team the time and resources to build it "right"? Did you even know what "right" meant? Or did you just want it shipped?

If you're an engineer reading this, stop accepting blame for decisions that weren't yours. The next time someone mentions technical debt in a retro, try this:

"Let's talk about the constraints we were working under when we made those decisions. Because I'm pretty sure we made the best call we could with the information and time we had."

And if they push back? If they insist it's "debt" that you "borrowed"?

Start interviewing. Because you're working for someone who doesn't understand software development and will always blame you when things get hard.

Top comments (0)