Technical debt repayment strategies

image

Tech debt: everyone has it, and every developer worthy of their title wants to pay it off, but how do you organize this process?

We implement crop rotation

In its previous article I compared the payment of technical debt to the importance of crop rotation in agriculture. If you continue to process a field (codebase) season after season in order to get a large harvest (complete projects, add features, etc.), and do not give this field a season to recover (payment of technical debt), then it gradually begins to lose its quality and productivity.

This metaphor remains appropriate for software development; in addition, it contains hints of possible strategies that can be used to pay off technical debt.

There is a surprisingly wide range of ways to pay off debt. And this is very useful as it gives us a lot of planning options.

For the purposes of this article, we will assume that you are working in an agile development methodology, but many of the principles, if creatively refined, apply to other methodologies.

Dedicated sprints to pay off technical debt

In complete analogy with crop rotation, we can stop working on features every fourth sprint or so, allocating it only to pay off technical debt.

Pros:

  • Developers share a common drive to focus solely on paying technical debt
  • Developers can coordinate to pay off larger chunks of technical debt by working in tandem
  • Businesses are motivated to study technical debt results that demonstrate the importance of work and the remaining volume.

Minuses:

  • Merge conflicts begin to arise as employees make larger volumes of architectural changes.
  • With this chaos and instability, it can be difficult to tell if something is broken if there is no good test coverage.
  • Just because you are working on technical debt, support incidents never go away. Without staff to help with the escalation of support requests, technical debt is guaranteed to be hampered by support.

Dedicated Capacity for technical debt repayment

In this model, the agile team reserves a certain number of points or a percentage of the total sprint capacity to pay technical debt on an ongoing basis. For example, in each sprint, a team can take 5 storypoins of various debt repayment jobs.

Pros:

  • This ensures that paying off technical debt is part of the ongoing culture of the organization.
  • Ongoing technical debt work may prevent the need for more work in the future.

Minuses:

  • If changes need to be made to the sprint, working on technical debt will be the most likely candidate for removal from the sprint.
  • By limiting your work on technical debt to small amounts, you make it harder to eliminate the sometimes large chunks of technical debt.

Dedicating employees to pay off technical debt

This is a hybrid of the last two options. Each sprint selects one developer to work on the technical debt while everyone else continues with their normal work.

Pros:

  • Partially retains the spirit that is present in the sprints allocated for the payment of technical debt.
  • By keeping other people actively working on standard tasks, project managers do not need to suspend project activities
  • Support breaks do not necessarily interrupt technical debt
  • This option allows you to pay off larger chunks of technical debt in a single sprint.

Minuses:

  • Large volumes of work focused on technical debt can still cause significant merger conflicts, although the risk is not so great
  • The work of an employee dealing with technical debt is likely to be interrupted anyway and transferred to other tasks if additional capacity is needed.

Payment of technical debt upon completion of work

In this model, when developers plan their work, they add to the plan the cleanup of neighboring code and the payment of detectable technical debt that is already in the work area. It corresponds boy scouts: always leave the parking lot (codebase) cleaner than it was before you.

In other words, this implies that when you touch the code, it should get better. In the code that is touched most often, you need to pay the highest percent on a technical debt, so it makes sense to pay off the debt in the areas of the code you are working on.

A similar concept is given in the book by Malcolm Gladwell The tipping pointfor an example from the New York subway. The City Transportation Authority found that by uncoupling subway cars, cleaning them of graffiti, and making sure there is no graffiti at all times, you can save money on broken windows effect, in which people believe that the state of the carriages does not bother anyone and the crime rate may increase. By reducing the number of rabbits and graffiti, the agency could also reduce the number of violent crimes on the subway.

If we transfer the same principle to our codebase, then we need to make it so that when you touch areas of the code, they are cleaned up and the technical debt is paid.

You probably guessed from what you read above that I am a fan of this approach, but let’s still consider its pros and cons.

Pros:

  • Tech debt pays off in areas that developers naturally touch more often
  • You no longer need to “allocate space” to pay technical debt, it’s just part of the workflow
  • Merge conflicts are minimized because changes are made only in isolated areas.

Minuses:

  • There is no special opportunity to make large changes that affect the entire system
  • It causes “inflation” of storypoints due to the fact that additional work needs to be done with each ticket. This reduces the amount of work that can be done in each sprint.

Major code revisions

Above, I talked about the strategy of paying off technical debt by gradually replacing parts of the system, as in Thought experiment with Theseus’ shipbut what if that’s not enough? What if you don’t have time to replace all the software piece by piece and need to make more radical changes?

Here are some ideas to help you:

Breaking an application into smaller applications

With this methodology, we split the monolithic application into smaller applications. Often this approach is complemented by Domain Driven Design and / or microservices, but its main point is that if the application is too large to replace, it can be divided into smaller parts, the replacement of which is realistic, after which you can replace each part one after the other.

Also, this scheme can be implemented using Strangler Application template Martin Fowler, in which a new application is created, receiving the same requests as the old one, and making calls to legacy systems until a modern replacement is ready for each of them.

Pros:

  • Allows you to strategically manage the most important aspects of rewriting without having to shoulder the burden of an entire rewriting project
  • Reducing parts of the application reduces the likelihood of complete code rewrites in the future

Minuses:

  • Initially, this approach only increases the complexity, while the technical debt is not paid off.
  • More points of failure and more variety of problems appear

Prototyping applications in spare capacity

In this model, developers can use slack time or time allocated for technical debt to work on long-term projects, such as replacing part or all of an application. Once sufficient progress has been made and the work can be started in earnest, these tasks begin to be implemented into a sprint or sprint series for formal implementation and delivery.

Following this pattern, I have been very successful in porting JavaScript applications to TypeScript, including spending time outside of work (not necessarily, but I decided to do so) and waiting for the online regression testing environments to come out.

Pros:

  • Potentially defective prototypes that are not tied to formal QA / supply cycles can be identified and addressed
  • When the work is ready to be included in the sprint, it is already usually a very concentrated work, in which most of the unknown variables are solved.

Minuses:

  • It can be difficult to find a significant amount of off-schedule prototyping time unless your organization wants to reduce resource allocation to other projects.

Full transition to the new application

In this model, all work on the old application stops, except for the fixing of critical bugs, and work begins on the application, which will become its complete replacement. This is what people usually mean when they talk about rewriting an application.

Pros:

  • Employees can focus on the new system without really considering the existing one.
  • The total execution time may be less

Minuses:

  • With very short delivery times, the business may feel like they are wasting money on the project.
  • Delays in deadlines can interfere with the delivery of the required work
  • In fact, this approach turns into an all-or-nothing principle.
  • May not fully consider all risks before investing in a new platform project

findings

Consider these options for continually updating applications, as well as more radical options. In my opinion, there is no one the best option, you need to look for the one that works best for your team, product and organization. Evaluate these approaches and determine which options work best for you when preparing a “crop rotation” to keep your codebase healthy over the long term.

Similar Posts

Leave a Reply

Your email address will not be published. Required fields are marked *