Revolving Tech Debt

Cover photo credits: @ExpLatinAmerica. Learn more here.

Avoiding debt is hard, nearly impossible. It is even harder to get rid of it. But the hardest thing is figuring out the how. Just exactly how do you get rid of tech debt? And would you want to?

Here are some loosing strategies:

Strategy #1: Dedicate 20% of the sprint to tech debt.

Why it fails: besides the fact that humans are terrible at working in percentages in a multiplex environment, that 20% will be the priority battleground between engineering and stakeholders. How do you respond to "...tech debt can wait. If we don't get this out by next week, might as well there be no product..."? Well the rational answer is you can't. Feature wins, tech debt looses. You would think this will change in a bigger team. Nope. Bigger teams do have more capacity but they are also more expensive and the stakes are higher.

Strategy #2: Let's sneak in most of it on feature estimations. Nobody will notice.

Why it fails: Yeah. Nobody dumb enough. While this is a great strategy for the most basic kind of tech debt, it won't scale with for paying off large chunks of it. It will artificially inflate each estimation and the team will just fail to deliver critical stuff on time. Tech debt will ultimately become feature debt. And if there are multiple teams, velocity comparisons will quickly unravel that dirty magic trick.

Strategy #3: The Revolt - after X many months of accumulating lots of technical debt the team finally looses it: "That's it. We're going to force some tech debt into the next sprint and no one can stop us!!!"

Why it fails: setting aside the fact that revolts are risky business, even if they work, having uneven value distribution being delivered over time will quickly increase an organization's risk in the marketplace. It might feel like an internal victory but in a tight market race hitting the brakes on shipping continuous value for a moment is all it takes for your competitors to quickly get ahead. It can all happen in a blink of an eye.

So what is tech debt anyway?

Technical debt describes all shortcuts a team takes to achieve a goal in the short term making it difficult for the team -- and ultimately the business -- to succeed in the long term.

I like to think of it as using a credit card: you can swipe it to buy whatever you want but at some point you are going to have to pay it back. And just like a credit card, tech debt earns compound interest over time with a pretty high interest rate (consider how quickly code goes stale today).

So, how should you pay it off?

A. Transactor: You can pay it all back as soon as possible, but you may end up with no liquidity to pay for other things. [no teams ever do this although many want to do exactly this]

B. Delinquent: You can pay only the bare minimum regularly, but in the long term you may become delinquent and default. [many teams end up unintentionally doing this]

C. Revolver: You can pay an amount less than balance due such that you have enough cash in hand but large enough so you avoid incurring too much interest. [more teams should be doing this]

I believe the correct answer is C. Option A means a team cannot react to market demand if it is too busy paying off debt, and option B means there is a looming default event for this particular product or system in the future that an org may not see coming until it is too late.

But the biggest advantage of option C is that when combined with strong planning and feedback loops, it can identify opportunity windows to sometimes pay back a lot of the debt quickly, particularly during a moment when the market pressure is low. Strong feedback/planning can also identify opportunities to write off tech debt. When an org decides to discontinue  products or features that are no longer enabling the business, the related tech debt also becomes void. Goodbye.

A strategy that works

A strategy that works well is a multi-faceted one with at least three dimensions:

  • Definition of Done
  • End-of-Life Projection
  • Engineering as Stakeholders

1. Definition of Done
An organization is better served if some aspects of tech debt are rolled into the Definition of Done for how product is shipped. The following should not be categorized as technical debt but instead they should become part of the shipping requirements for any feature:

  • Unit Test Coverage: this may not make much of a dent in shipped product quality but it is the only way for a team to collectively maintain and refactor code over time without significant risk.
  • Critical Path Integration Tests: these will definitely put strong assurances on shipped quality.
  • Observability: logging and telemetry are as critical as your windshield, mirrors, and dashboard are to driving a car. Why bird-box your driving?
  • Deployment Configuration: doing this right from the beginning significantly reduces downtime risks due to configuration changes down the road. There are no net gains when short-circuiting this process.

2. End-of-Life Projection
The most common mistake teams make is not computing and communicating the capacity/occupancy limits for a shipped feature that was delivered using shortcuts and incurring tech debt. Business stakeholders are often not aware that a shipped feature has scale limitations and, depending on the growth rate, those limitations are already setting a life expectancy for that feature.

Set and communicate capacity and end-of-life expectations clearly from the beginning and one of two things is likely to happen:

  • stakeholders could be open to invest in the more scalable solution which could mean current tech debt becomes regular feature development.
  • or, they could be fine with the life expectancy for that feature for the short term, but may want to regroup in the future to discuss redeveloping this feature for the next level of scale.

In the first case tech debt is not erased but significantly reduced. In the second case tech debt is not recorded as such as there is a clear end-of-life for this feature. Instead, tech debt could become the roadmap for the v2.0 of this feature.

3. Engineering as stakeholders
Consider what engineering teams typically work on during a sprint: a todo list prioritized by a product owner. The product owner has come up with that list by negotiating with several or many stakeholders: people or teams who have a stake in the code being shipped so they can advance one of their business goals, for the good of the organization.

Teams...needing to ship code....to advance....their goals....for the good of the organization...you say? That is exactly what engineering teams are trying to do when wanting to pay off tech debt.

What if, just what if:

Engineering teams take on a stakeholder role during planning and prioritization round table. Just like any other team, they will need to make their case to get sprint time for tech debt items they believe will advance their team goals for the greater good of the business.

They no longer have to find ways to justify doing the right thing for their organization or hide their incredibly valuable work under other features.

Tech debt becomes just regular feature delivery and shipping comes with the same recognitions and celebrations as any other feature that advances goals of any other team in the organization.

What's even more valuable, this approach provides a two-way checkpoint for the team: having to explain the value of tech debt to a non-engineering audience not only helps develop strong cross-team communications but it can also help engineering double-check their own thinking and avoid paying off tech debt that does not advance any business goals: "Is this tech debt really valuable or just a cool thing I am itching to work on?"

Tech Debt Utilization

Just like credit card consumers are advised to not exceed the ~30% credit utilization limit in order to build and maintain their credit, it is similarly a good idea to limit tech debt to around 25%-30% of the total points of the backlog. In the credit card example, credit utilization is the ratio of the current balance due over the credit limit and that can be translated to tech debt as:

Tech Debt Utilization = (Tech Debt Balance / Total Backlog Balance) x 100%

However, in order to compute the balance, it is critically important to first record all new tech debt correctly. This can be done by creating and estimating tech debt PBIs (product backlog items) for each shortcut the team takes, just like a credit card balance is augmented with each purchase during a merchant transaction.