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 (30)

Collapse
 
aloisseckar profile image
Alois Sečkár

Why do you think manager didn’t push his team under pressure deliberately? Or more likely because there wasn't any other viable option at the moment except inventing a time machine and travel back in time to prevent that bad decision that caused such situation.

I like your hoisting of the problem from engineering to management level, but I don't see a reason not to keep calling it a "technical debt". Everyone understands the term and the substance remains the same - the code is technically bad and it is causing technical problems because someone decided not to solve them in advance in exchange for some quick wins. You're just blaming other kind of people for creating it.

Collapse
 
adamthedeveloper profile image
Adam - The Developer

You're right that managers often don't have better options because they're usually caught in their own cascade of impossible constraints. The VP needs numbers for the board, the board needs metrics for investors, and nobody in that chain is getting the time or resources they actually need either.

But here's why I still think the term matters:

"Technical debt" frames the problem as a moral failing that needs to be "paid back." It carries all this baggage about borrowed money and responsibility and whose fault it is. When you say "we have technical debt," leadership hears "the engineers screwed up" even if that's not what you mean.

Compare that to saying: "We optimized for speed in Q2 to hit our fundraising milestone. That bought us 18 months of runway. Now we need to allocate 3 engineer-months to address the maintenance costs of those decisions."

Same situation. Totally different framing. One sounds like accountability and planning. The other sounds like blame and cleanup.

The substance isn't quite the same because the metaphor shapes how we think about solutions. "Debt" implies you should pay it back ASAP and feel bad about having it. "Maintenance cost" implies you should budget for it as a normal part of doing business.

You're right that I'm just shifting blame up the chain, but my real point is we should stop playing the blame game entirely. The system creates these pressures. What we need is honesty about trade-offs and realistic budgeting for consequences, not finger pointing about who "borrowed" what.

Though I'll admit: if everyone's going to keep saying "technical debt" anyway (and they will), then yeah, at minimum we should all be honest about what created it instead of pretending it materialized out of thin air.

Collapse
 
teek01930 profile image
Teek

If they hear "engineers screwed up" when you say "tech debt" that's on the person presenting it. Not the leadership and not term.
The idea that it is "money that needs to be paid back" is correct! At some point, someone (a dev or other) decided to borrow against the future for the sake of simplicity (or familiarity) right now. And when you start having problems, that is the debt coming due.

Collapse
 
igorsantos07 profile image
Igor Santos

I understood the article as a bit of an exaggerated story against using "tech debt" as an umbrella term. It does fit a bunch of scenarios, but it's more meaningful if we start using more specific expressions for other cases which were not simply to "borrow time".

Collapse
 
teek01930 profile image
Teek

I came here to say something like this! Thank you!
Tech debt is a useful term that this writer has had weaponized against them too often.

Collapse
 
miketalbot profile image
Mike Talbot ⭐

Great post!

I've always considered myself an engineer, not an artist, even though a lot of our work is creative. As an engineer, my job is to get people over that river by building the best bridge possible. That doesn't mean it's the most beautiful bridge. It doesn't mean it's the most elegant bridge. It doesn't even mean it's the most efficient bridge. It just means it's the one I could build that was most appropriate at the time.

Collapse
 
xwero profile image
david duymelinck

I think the cost of learning should also include only having theoretic knowledge. To ride a bike you know you have to hold the handlebar to steer and push on the pedals to get speed. But the first time doing it is awkward.

Collapse
 
adamthedeveloper profile image
Adam - The Developer

This is a great addition. The gap between knowing a pattern and executing it well is real - and invisible to people who’ve already crossed it.

You can understand dependency injection in theory and still completely fumble it in practice: over-inject everything, create circular dependencies, end up with a constructor that takes 47 parameters. That’s not technical debt, that’s what learning actually looks like.

This awkward phase is unavoidable. You don’t get smooth without being clumsy first. Imperfect code written while learning is a normal cost of growing engineers, not a failure.

The problem is when orgs treat this learning cost as corner-cutting, or assume hiring seniors makes it disappear. Even senior engineers are juniors when they’re learning a new domain, framework, or pattern.

Collapse
 
teek01930 profile image
Teek

It is NOT invisible to actual competent people who have crossed the line. Some of them/us remember the effort and recognize what it takes. Honestly that might come from teaching.... but it is not and should not be okay for it to be invisible once you cross it.

Collapse
 
ben profile image
Ben Halpern

maybe

Collapse
 
chrisrichter profile image
chris-richter

This isn't a great post because of really any groundbreaking conceptual realizations, but holy hell did you hit it on the head with respect to framing.

For us as developers, architects, engineers and co., perhaps we could do a better job of quantifying future costs, but to what end? If the main objective is secure series x of funding, that feedback becomes not only not a now issue, but words they won't even hear (and we probably wouldn't be correct).

Loved your post. To whatever holidays you celebrate or none at all, I hope they're great (or I guess I could have an uncaught null there).

Kindly,
Chris

Collapse
 
adamthedeveloper profile image
Adam - The Developer

Haha, with this current velocity of the evolvement of software development, I try NOT to invent anything new ( or groundbreaking if i could ) but I believe there's so much more to the existing concepts that I believe we should look more into it and maybe re-evaluate it to adapt to evolving contexts.

And thank you! In Cambodia here, Christmas isn't really a cultural or a big thing, but it's growing, especially here in the capital city in Phnom Penh where I live - I'm pretty much one of the only few here with a full, overwhelming Christmas spirit every year but I'm happy to be all over in my head all by myself haha.

Collapse
 
teek01930 profile image
Teek

"evolvement" the word you want is evolution.

Collapse
 
sloan profile image
Sloan the DEV Moderator

We loved your post so we shared it on social.

Keep up the great work!

Collapse
 
adamthedeveloper profile image
Adam - The Developer

Thank you!

Collapse
 
the_arkitekt_2fd582543623 profile image
The Arkitekt

While I agree with much of this, it is a gross oversimplification, and doesn't do justice to what happens in the real world. And now with AI, while it might be able to minimally help with fixing existing debt, the amount it is going to generate will be overwhelming and there won't be any real devs left who know how to actually do the job. Its gonna be a crazy time.

Collapse
 
ribab profile image
Richard Barella Jr.

We call the tasks that don't contribute directly to product features as "Enabler" tasks rather than having everything labeled as "Stories".

So rather than calling it technical debt we call it Enablers

Collapse
 
adamthedeveloper profile image
Adam - The Developer

I like that framing. Calling them Enablers makes the intent explicit: this work exists to make future work faster, safer, or even possible at all.

What I’ve found is that once you name these tasks as enablers instead of “debt,” the conversation shifts from “why are we cleaning up?” to “what does this unlock?” It stops being about fixing past mistakes and starts being about increasing delivery capacity.

Same work, different language.

Collapse
 
sylwia-lask profile image
Sylwia Laskowska

That’s exactly how it looks! Especially when it comes to slightly older code. On the frontend, I sometimes feel like the code is already legacy the moment a project starts 😄 A new library or store pops up right away, the version gets bumped, and boom - we already have “technical debt” 😄

Collapse
 
adamthedeveloper profile image
Adam - The Developer

haha frontend development is the perfect example of why "technical debt" is broken.

You're not in debt because React 19 came out three months after you chose React 18. You made the best choice available at the time. The ecosystem just moves absurdly fast.

Calling that "debt" implies you should have predicted the future or made a mistake. But what were you supposed to do but wait indefinitely for the "final" version of JavaScript tooling? (Spoiler: there isn't one.)

pure entropy. The code didn't get worse, the world around it just moved faster. Budget for it as a maintenance cost, not a moral failing.

Collapse
 
teek01930 profile image
Teek

"debt" in NO WAY suggests one made a mistake.
Most adults are in debt due to paying for medical costs or education.
What you are actually suggesting (reasonably, I think) is that we need MORE WORDS than tech debt. We need something to cover "keeping up" and "erosion of the platform", etc...

Collapse
 
jp_fontenele4321 profile image
JP Fontenele

I felt this post, sometimes I frame these known shortcuts as fast follows. So I take them and deliver the bulk of the feature, while saying "this will break soon, we have to have time to work on making the feature solid". So far it has been working to some degree

Some comments may only be visible to logged-in visitors. Sign in to view all comments.