Don’t fix it just because it’s technical debt.

Many kinds of problems get classified as technical debt. Most generally it’s problems where:

  • In the past, we made a decision to borrow against our future productivity in order to achieve earlier product delivery;
  • Because of that past decision, we must now make recurring interest payments in the form of wasted effort.

Engineers hate waste. Waste makes us want to barf. So it’s obvious to us that technical debt must be faced head-on and paid down. We therefore propose to management, “Let’s take technical debt more seriously.” Management usually replies one of two ways:

  1. No. We have to keep setting aggressive feature deadlines. We don’t have the luxury of looking back.
  2. Sure! How much of your time do you want to spend on tech debt reduction? How about 20%?

At least #1 is internally consistent.

#2 is scatter-brained. Why should we only spend part of our time doing work that maximizes value, and the rest of our time doing other, less optimal work?

A realistic manager would say, “If you have a proposed improvement that’ll reduce wasted effort, then make a case for the soundness of that proposal as an investment.” If we can save 32 labor-hours over the next 3 years, but it’ll only cost 8 labor-hours to do it, then maybe let’s do it. If it’ll cost 40 labor-hours, then you should just keep on wasting that effort.

Reducing wasted effort may feel like an obvious good, but reducing wasted effort isn’t the goal of a company. Making money is.

18 thoughts on “Don’t fix it just because it’s technical debt.

  1. Great article!

    Automate-all-the-things doesn’t make sense if we spend more time building the automation than the time it would save over a given time period.

    But many engineers would _prefer_ to work on an automation project over the prospect of adding a boring recurring item to their task list.

    There is a breaking point with technical debt when it translates to monetary debt. Finding 10 engineers for an outdated language on a poorly built platform to build a feature which could be done in the fraction of the time/effort on a newer system is the point where companies are overtaken by their competitors… who come to the party later and build better.

  2. ilan's avatar ilan

    This is a great point, but it doesn’t take into account the psychology of the situation.

    A good developer experience leads to happier and more productive developers, beyond the extra effort needed to “pay the interest” on the technical debt.

  3. ystoneman's avatar yannstonemangmailcom

    In addition to the practical considerations, there’s a psychological aspect to technical debt. Unmaintained code can lead to new code being written in a sloppy way, like how a single broken window in a house can lead to the entire property becoming rundown.

    Robert Martin discusses this in “Clean Architecture,” emphasizing that visible signs of neglect can demoralize teams and encourage further neglect.

    Addressing technical debt isn’t just about immediate efficiency—it’s about fostering a culture of quality and long-term sustainability in our codebase.

  4. Great Article and very insightful.
    Technical debt is an issue that needs to be dealt with and fortunately, there are a number of tools out there that can help with identifying and dealing with technical debt.
    I would say that it’s easier to make the case to look back and tackle technical debt if you have an organised and efficient way to identify where the issues lie.
    Managers may indeed be more willing to allocate the time to deal with technical debt if the development process is streamlined, efficient and easy to understand. One tool, and I must admit, I’m slightly biased as I have been working with this tool for many years now is Understand by SciTools. Understand does exactly what it says on the box and helps developers understand their code base by analysing the code, building a database and giving the development team instant valuable insights into their code in the form of architectural analysis, “Always On” defect checking, graphs, charts, heatmaps, complexity and technical debt analysis, standards compliance and much much more.
    jason.mcallister@emenda.com

  5. “In the past, we made a decision to borrow against our future productivity in order to achieve earlier product delivery;”

    Has anyone tried to measure how much earlier making technical debt lets you get to product delivery ? I don’t think that the savings are that high. To be honest I think that most of the technical debt comes from lack of good analysis on the first time; under urgency you start putting up code without an overall design and all those design decisions not taken make up you dept. Good design might even end up getting faster to product delivery.

    1. > Good design might even end up getting faster to product delivery.

      I agree. And I think this fact puts the lie to the “debt” metaphor. Taking out a loan isn’t supposed to make things go slower.

  6. Riley's avatar Riley

    Eh, this is true to a certain degree. Technical debt makes future “value add” code take longer though. Find a middle ground, and refactor as you go – and do a better job of planning for possible future tweaks by spending some time thinking about it instead of just jumping in and building it. As is, this article is pushing a very short-sighted view that presumably PMs would love.

    1. > this article is pushing a very short-sighted view that presumably PMs would love.

      LMAO – maybe you’re right.

      I agree that it’s short-sighted not to take into account the total cost of ownership of the thing you’re building, and that includes the labor cost of maintenance and repair. But I would argue that you must somehow discount the value of any future labor savings, e.g. by setting a time horizon by which investments in maintainability are expected to pay off.

  7. Mike K.'s avatar Mike K.

    Wow, I couldn’t disagree more with this article. In the end, most (but I’ll concede not all) of the technical debt converts to technical risk. However, consistent tech debt usually creates unmanageable, hard to manage sprawl, that hinders or prevents adaption of new techniques or technologies that keep you current in the marketplace. You may not, and probably won’t, feel the pain the first year, but by year three you often start sighing when you have to manhandle the out of date, undocumented, jerry-rigged, hodge-podge of technology into submission for something that should be a basic tweak.

    Now, having a serious look at tech debt prioritization I can definitely agree with. But throwing the baby out with the bathwater as you suggest just doesn’t make sense to me.

    That’s like my teenage daughter making an argument to not clean her bedroom when it looks like it puked clothes, food wrappers, books, and boxes all over the floor. She would say, “I can hop open section of the floor to open section of the floor to get to my desk or bed so I am OK”. I would respond, “Eventually you will trip and crack your head on your desk or bring bugs because of all the food wrappers”. That’s money spent on an exterminator at best or the ER at worst.

    1. I think you and I are basically in agreement that it’s worth spending the time to do things right. But our capacity to do things right is always subject to the constraints of time and labor power, so you always have to do things “less right” than you could’ve if you’d had more time.

      That’s why I don’t think it’s helpful to classify some system shortcomings as “technical debt” and others not. It puts our focus on decisions which happened in a context that’s no longer relevant.

  8. Jander's avatar Jander

    And who decides the time span in which to calculate the cost benefit? You mention 1 year. Why not 1 month, or 18 months or 5 years? The idea that determining cost benefit in technical debt is as simple as quickly calculating person hours is just false. It’s a complex subject and, as others have mentioned, does not simplify this easily.

    1. 100% agree. I advocate that teams explicitly discuss what this time span should be and arrive at a shared answer. It’ll be different for different teams.

  9. Jok's avatar jok07

    I see where you’re coming from, but I don’t agree that creating technical debt should be the go-to plan. It’s like taking on more and more credit card debt every month – it’s just not a good idea in the long run. If we keep choosing to cut corners with code to ship features faster, we’re going to face bigger and bigger problems later. It is rare that debt is just a fixed cost like your 32-labor-hours work, this will be a recurring cost, paid forever until fixed.

    I think technical debt should be a rare exception, not the rule. And when we do take on debt, it needs to be written down with a solid plan to pay it back. That way, we’re staying on top of it instead of letting it spiral out of control.

    Plus, a lot of tech companies aren’t just trying to make a quick buck (to address your concluding thoughts “reducing wasted effort isn’t the goal of a company. Making money is.“). They want to solve real problems. The best companies focus on making a great product first, and the money follows. Technical debt can really get in the way of building something that works well, scales smoothly, and is easy for developers and users to pick up.

    So while I get that there are always trade-offs, I believe that actively managing technical debt and aiming for high-quality code should be a key part of any plan for long-term success. By doing this, we can create products that are easier to maintain, can grow with the company, and ultimately do a better job serving their users.

  10. Pingback: Daily Links: Friday, Jun 7th, 2024 | From Pixels to Particles

  11. Andy's avatar Andy

    I think it’s important to distinguish between different types of “tech debt.” We incur them in different ways and should justify/address them in different ways.

    • Maybe it’s a misnomer to call it tech debt, but I often hear the term applied to the effort to upgrade to the latest versions of our architectures and dependencies. This is a pain-in-the-butt; we didn’t incur this debt by doing anything wrong; we didn’t even get any payoff up front! But ignoring it for long creates unsecure and broken software. It’s important for this kind of “debt” not to come as a surprise to project leadership. They never asked for it, but it should be expected regularly in modern development.
    • One kind of tech debt is “fixing your mistakes.” You rushed code into production without good code review or testing, and now you have bugs, or maybe you have code that works but just wasn’t written the best way, and its antipatterns will make it harder to update in the future. You have poor architecture, repeated code, hard to reason with, etc. So because you didn’t have time to do it right at the time, you set aside time to do it right later. This is the worst kind of technical debt, and perhaps the most preventable. IMO it’s a lie to model this as something that’s planned on in advance—or if so, it’s a bad plan. It’s not like: “It will take a month to ship.” “How much if we use antipatterns?” LOL! Typically the time cost of “doing it right” after release is about the same that it would have been in the first place. No time was really saved when incurring the debt; it was just an unfortunate mistake that could have been avoided with more oversight, better design, better communication, etc. It doesn’t “borrow time” from the future and ship earlier; half the time it actually delays releases as unacceptable bugs crop up. More often, it’s just an excuse used when the shortcomings are discovered—”No time to fix it now, we’ve come too far; ship it and call it tech debt.” Smart teams won’t merely fix this mistake and move on, they’ll learn from it what could have prevented it in the first place.
    • One kind is “cleaning up after yourself.” You shipped a feature, but now you need to expand (or write!) the unit tests and document it all. This kind, perhaps there are very legitimate arguments to be made about skipping or streamlining it. Unit test coverage is just a number. Does it catch bugs? Is it worth exhaustive documentation on a feature that will be thrown out after A/B testing?
    • So what would be better than all of this? I’d like to pitch the concept of “Feature debt.” I guess Agile says “mvp,” and I guess the idea is that whatever you’re shipping is the leanest, most stripped-back version possible. But I find that’s rarely the case. So if you want it faster, you usually don’t cut any corners by asking to sacrifice quality. Sacrifice quantity instead. Ask “What can we change about the design, or omit from the functionality, to speed this up?”
  12. Technical debt should of course not exist in the first place. To be able to fix it, when it exists, also means that people will learn from their past mistakes and do better in the future. of course, we are humans, born with flaws inside, so we probably always make mistakes.Are those mistakes bad? Well, they can be if in that piece of debt, is also hiding hard to maintain code, or even undetectable bugs. Sometimes for a company, it’s better to invest a bit of time in “cleaning the attic” before it gets out of control.I wrote a linter to detect Cognitive Code Complexity, just to detect if code is starting to get too complex, which will lead to code that is hard to maintain. Just a way to check if developers might create the next piece of mess.The more maintainable the software is, the easier it is to keep out that digital trash.

Leave a reply to Dan Slimmon Cancel reply