What is technical debt and do you have to pay it back?

In this post I invite you to consider the more the technical side of things in your product, even if you don’t fully “get” technology. I’ll take you to the understanding of what is technical debt and then we will explore if you have to pay it back.

Yes, if you have to pay it back.

It is important to understand the definition of technical debt and its impact because it’s a concept a ton of people mention, but very few people master. As a coach, once you get to understand it you can help any technical team. And I’ll tell you: there are not many coaches out there capable of helping their teams in the technical front, so this gives you an unique advantage.

Let’s jump into it!

First, a word on flaccid Scrum

I know it’s a funny name. I did not invent it. Martin Fowler did coin the term “flaccid scrum” . And if you don’t know who he is, he is a brilliant software developer from the trenches, with tons of published books and one of the signatories of the agile manifesto. I’d say he knows a thing or two about agile and about software.

I agree a ton with it because I used Scrum in the trenches for many years and I observed people getting obsessed about the ceremonies (now called events) and getting a bit lost on how to actually develop the product. In my case, mostly software.

Engineering practices are important. Building commercial products require a level of rigour that translates into quality for the customers.

While I see an explosion in Scrum adoption, I still see Scrum Masters, Product Owner and teams a bit lost on how to create great products on the inside. They are over rotating from thinking too much about the product (and never delivering) towards thinking too much about the customer (and delivering fast with questionable quality).

Remember, agile is technology and business together. Everyday. Not one versus the other.

Scrum does not address technical engineering practices, so you have to go outside of the framework if you want to be helpful coaching your teams, leaders and departments.

Now, while technical knowledge is needed of course to address technical debt, there are a lot of considerations that you can bring to your people as their coach, even if you do not understand code.

What most people won’t tell you about technical debt

Let me start by shocking you a bit:

Technical debt does not exist.

That’s right, that is my opinion as an agile coach and as a former software developer. This is the best way to think about technical debt. It does not exist.

Think about your product development holistically. If you are printing a book, issues with the press machinery and software can be a problem. Dealing with typos is a fact. How to sell your book in multiple platforms can be tricky. All this is part of the technology behind your book-making skills and they all need to be in the best shape to produce the best quality book possible every single time.

It’s similar if your team develops a software product. There are elements on how to create the code, build the code, deliver it, and maintain it in good health that needs to be taken into account at all times, whenever we put something out for the customers.

If you look at it this way, there is never a technical debt and therefore you never need to pay it.

However, I guarantee as an agile coach you will:

  • find organizations that allow the code to produce technical debt.
  • be asked in general what is technical debt and how to pay it.

in the end of this post, I’ll teach you some strategies to make sure this holistic approach can be put in place. The solution to fixing and to never accruing technical debt is actually the same.

But first, let’s look into what is a proper definition of technical debt.

The definition of technical debt

Technical debt is a concept created to help businesspeople and developers understand together the impact of their choices as far as implementation and timelines.

I find the definition of Ward Cunningham and Martin Fowler kind of fun, and it’s something like this:

Consider that every code created to solve a problem for the customer has its inherent complexity. And consider some of that has unnecessary steps, choices and pieces that for lack of time or lack of knowledge every developer introduces.

Sometimes it’s a part of the code that gets full of crap, like a class or a few files with dead code or spaghetti code.

Sometimes it’s a whole design piece that gets crappy (like in the database, in a rule engine, in an architectural piece of the software).

That “crappy” or “extra” aspect is the technical debt.

OK, now let’s think literally debt from the economic concept.

Debt is neither bad nor good. It is something that you pay once you have it and want to remain a citizen in good standing. Sometimes you pay it fast, sometimes slow. Great decisions on how to manage your economic debt have to do with your interest rate. Make sure to focus on paying what has a high interest rate so that you don’t keep accruing more debt and go bankrupt.

Pay what has a high interest rate so that you don’t keep accruing more debt.

What is that in software?

Adding a new feature of piece of code should take standard time and quality for your team. If something that would usually take 5 days to be developed now takes 7, be warned. That area of the code is probably accruing debt.

You have a piece of the code that every time someone touches causes more bugs. Or that every time you want to add a new feature you notice the team gets slower and slower. That debt is increasing. That is the debt you want to start paying asap. Like in the picture below.

what is technical debt

Not every “apparent” crap or extra is technical debt. And not all debt is worth paying at the same speed.

That brings us to the next section.

If it’s not a problem, it’s not technical debt

That’s it, I’ve said it.

Older technology can be in the best shape. New technology coming into play is not necessarily adopted to repay debts either.

Because something is made in COBOL it’s not a technical debt. Because your software is run in mainframes, you do NOT have a technical debt in your hands. Normal software evolution is not technical debt in principle.

If given the people with the knowledge, the product can still be evolved within time and quality standards for your team, you are not dealing with technical debt.

Wanting to evolve your database to a more recent one, change the version of JVM (for the Java folks out there), move from standalone servers to the cloud… none of that is technical debt.

Remember, business and technology together in designing and owning the product. To service the customer at our best, we need both. We don’t just create in our software products the stuff the customer asks for, especially when the customer has no clue about technology. Evolving technology needs is just as part of the product roadmap as anything else. More on that in a bit.

Technical debt is about where in the code we are prevented from going faster, where every time we touch the code there is insecurity and inability to go further.

How do you know then if this is for sure a problem, a debt that needs to be repaid?

  • If a developer is afraid to touch code because things can go bad, it’s a technical debt that needs to be addressed. It’s also the same if only Jared can touch that part of the code. This should not be Jared’s playground; the code ownership is shared.
  • If it affects speed of delivery because nobody understands that piece of the code or it’s hard to add new components, it’s a problem and worth addressing. Ability to embrace change.
  • If you have a problem to add new tests to assure the quality of anything on a part of the product, you have technical debt there worth addressing. Remember technical excellence!
  • If it affects the morale of your technical teams, it is a problem and it is worth addressing. Motivated individuals anyone?

I’ll leave you with two more thing to consider that you should coach your teams and leaders about.

Bugs are not technical debt.

They are either a requirement that you just discovered (nor harm no foul) or they are lack of quality. For the latter, fix it asap. For the former, consider IF you want to accept that requirement ans plan for it accordingly.

Terrible code and poor design that NEVER gets touched is actually stable debt.

Stable debt does not accrue interest. It’s like something without interest rate. You can pay it much, much, much later. And there is where the economic analogy breaks a bit but bear with me. Consider that this MAY one day accrue the interests if and when that part of the code or the architecture needs to change.

It IS POSSIBLE it never will.

So, not every bit of “crappy” area in the code deserves immediate attention. Just awareness of its existence.

Consider it a cautionary tale to build things with quality the first time around.

What causes technical debt?

Technical debt as understood by most organizations is always a decision-making issue.

Since it’s in fashion to think every problem is a management problem, here is a famous thought on how technical debt is created.

Management intervention is just one of the ways in which we create and accrue technical debt but not the only way.

You definitely want to coach your managers and leaders on that front though. Here’s what can happen:

technical debt in a systems thinking loop

But technical debt can come from many front. It can stem from:

  • Poor judgement: especially when the technical team is not given all the pieces of the puzzle (or when they are not interested in it). Knowing exactly the intentions for a functionality, who uses it, how it can possibly evolve, etc. Software is produced on top of an architecture, and you want your architecture to support the actual need. Don’t let your developers blindly create “just that little something” for the next release. Treat every evolution of the product with respect and be thorough.
  • Lack of knowledge: do you have only junior developers or is everybody new to the technology at hand? The more you have people who don’t fully understand how to implement the technology, the more you risk of creating subpar solutions. It’s just the name of the game. Especially when you don’t have time to let people learn first. And that leads to
  • Shortcuts: either because it’s midnight and people want to go home, it’s release week and something must go out of the door, management doesn’t want to miss an important date this quarter… then people can default to doing the bare minimum.

What is interesting in the elements I just mentioned is because knowingly or not we are all making a trade off decision about how much we can do now and how much we will catch up later. Not catching up is the main generator of technical debt.

And here I go again with my broken record: the agile principles together are what sets the context for great agile software development. Working software is not simply code that runs. It’s code that runs with good performance, which is produced adhering to the quality standards and that solve a problem for the customer.

You can’t just solve the problem for the customer with a half-baked script. That is not decent software development.

You can’t just deliver amazing software that is useless for the customer. That’s being in an ivory tower.

A final word on technical debt accrual:

There are pictures like these circulating the internet, saying your decision on taking on technical debt can range from reckless to prudent, from inadvertent to deliberate.

source: https://www.imaginarycloud.com/blog/what-is-technical-debt/

I disagree with this picture. Sure, you can be inadvertent or deliberate. As in, you may or may not be explicit in your decision for going into technical debt.

But can you be prudent to accrue technical dept?

In my opinion, never. It is always risky, you just decided to take the risk. Like I said, you traded things off: deliver now, fix later. I’m not saying it is a bad decision, and many times it isn’t. but call it like it is: I’m stating it is a risky decision.

Strategies to avoid technical debt (and fix it if you have any)

I find the strategies to fix technical debt are just the same ones you use when you want to prevent taking on any. It’s not magic. Good practices usually have that kind of effect!

1 – Code standards and reviews

Say what you will, having peers look at your work is a great way to achieve quality. Creating the solution together instead of relying on Amy thinking alone in her corner is always best. You get the whole team or at least more than one head to critique your work. Everybody should have their work reviewed, including the most technically senior people.

Peer review, pair programming, coding norms, ideally some of that can be embedded in your static code analysis tool. A ton can be prevented or caught this way.

What happens to what you missed?

2 – Remove when you get there, continuously


Martin Fowler, the same one I mentioned described flaccid Scrum and technical debt, actually provides a ton of technical insights on his book that once was my bedside choice!

Refactor and improve code as you go. You arrived on a section that has no tests? You add tests. You arrived at a part of the code that looks iffy? You de-iffy it.

When you do it as you go it is just part of your team velocity. When you wait for later you have to have those meetings with everybody in, give estimates on how long it will take, justify why it needs doing, yada-yada-yada.

Remember: you don’t want your debt to accrue interest. In other words, something like the picture below.

technical debt interest rate

3 – Technical infrastructure in place

We don’t have time and smarts to check everything everywhere all the time. So, the best thing we can do for everybody’s happiness is arm ourselves with what technology can do for us.

Any software development team should have in place not only an automated CI/CD environment, but also in these environments have everything needed to run code analysis, performance analysis. These things can be so good as to check for code complexity.

If you are not a technical coach, you can still help your team take pride in building their “code for the code” or putting gin place the infrastructure that protects their product evolution. And not just the team. You want to sensitize managers and product people as well.

You don’t need to be the one naming the tools, you just have to know they exist. But I’ll give you just a few to start the conversation:

  • Jenkins as a CI/CD environment in many languages, from Java to Python.
  • SonarQube for automated code analysis.
  • Katalon for automating tests.

4 – Avoid short-term thinking

Now we enter purely human territory.

Short-term thinking is a nice name for “let’s do XYZ now and think about the rest later”.

You can make informed decisions or forego certain changes in the product. But when that is the default approach I think it warrants some more conversations.

A ton of the coaching on this front happens with managers to avoid the shiny object syndrome. It’s never just about this new thing you’ll add to the product. It’s about how the product can evolve to now offer this new thing.

It’s a simple way of reframing, but it’s very true. In a house analogy, it’s not just a new window or a new door you are creating. It’s the existing house now bearing these new windows and doors. Frames and structures will very likely need to change. The color might not match with the new items. You got the idea.

Proactive approach:

  • Have the team brainstorm and define explicitly in the team rules how they will be dealing with technical debt. Examine it frequently and evolve the rules. Help them enforce them, especially if they receive pressure from business folks.
  • Whenever new features come up, have the conversation on how much change it introduces, including what it can break, what needs to be undone or redone. It is not uncommon that architecture parts of the product might need refactoring from time to time and those are not as quick as refactoring just pieces of code. Make it part of the ritual in planning meetings.

Reactive approach:

  • If you will have to compromise based on timelines, trace right there the plan to catch-up. That is what makes it different than shortcuts and short-term thinking. It literally means something like “after this release, we will use the next 2 months to rework that XYZ”.
    • And that’s okay if the next release contain only that refactor. It’s quality, coming in early and often in the hands of the customer.

5 – Have a visible, transparent, aligned product roadmap

Like I mentioned before, it is most likely that at least once you will deal with one big element of technical debt. Maybe some legacy oversight that nobody fixed. Or… remember the argument “If it’s not a problem it’s not technical debt”? It was not a problem then, it is now.

Great! YAGNI (you ain’t gonna need it) is about tackling things when they need tackling. What was once a good business and technological decision, now is not.

That’s when you use this strategy.

Or when you took the reactive approach on strategy number 4 an k now you need to plan for the big rework.

At this moment then put it in the roadmap.

Since the product is more than just the buttons the user clicks, the internals of it are also to be weighed on importance and should be placed on the roadmap. This will allow that proper consideration. I mean, someone will literally have to say that the piece of technical debt is not a priority. And that person will be held responsible when things crumble down later. They cant’ play the card of “I don’t know”.

When something is in the roadmap it is prioritized relatively to the other items. A great agile practice of focusing on what’s truly important and keeping things visible, transparent.

What this also does is that it offers the important exercise of vulgarizing technical debt: describing it via its impacts. Nobody cares that your Struts 2 code is hard to maintain. They can’t relate, unless they are in your team. Can you express how much faster you are able to produce new features by tackling this Struts 2 infrastructure and replacing it with something better? Or how many less manual work might be involved (which increases automation an quality). That sort of thing.

We should all be able to express value in the work that we do and when the value is not clear, that is a great indication that we should not be doing it if there’s something else that has clearer stated benefits.

What if you are involved in the discussion of technical debt?

Address it head on.

You don’t need to be technical to be of service in this situation.

As the coach, there is one thing you can do: help people think and evaluate what’s in front of them and weigh their decisions.

Invite your people to a whiteboard session.

Have them list all they think is a technical debt.

Have them vulgarize the value on each element.

And invite them to the lovely world of analyzing a problem.

At some point, they need to see things relative to each other, as you can only fix one at a time.

technical debt prioritization

Its incredible how much discussion will come out of this.

In Summary

Technical debt is a decision making issue.

Old code is not technical debt.

It’s best to not take on technical debt and constantly and properly evolve your software.

If you have to pay it back, make it all visible in the roadmap, vulgarize the value of the technical debt items.

Technical and business folks need to work together to avoid or repay technical debt. It is not simply a team thing.

When all of that is considered… technical debt does not exist.

I hope this post shed some light on the topic for you as an agile coach, scrum master or maybe even a team manager. Let me know what you think and if your have any other questions on the topic. I’d love to hear from you!