Paying Down Technical Debt

Paying Down Technical Debt

By Stephen Darlington |  Dec 29, 2023  | software-architecture

Ask any five developers what “technical debt” is and you’ll likely get five different answers. To some, it’s an outdated framework and/or coding pattern. To others, it’s code that’s hard to work with. To still others, it’s the result of cutting corners to meet a deliverable. Let me throw out another definition: all code is technical debt.

Before you get out the pitchforks, give me a minute to explain. That outdated framework? It was once the latest and greatest. That tricky code? It (probably) was once elegantly designed. Software systems, like the universe, are prone to entropy. If you’re not actively improving a codebase, it is passively decaying.

Technical debt has a negative connotation, but let me try something else out on you: not all technical debt is bad. Technical debt is just like the debt you take on in life. If you don’t pay off your credit card every month, that’s debt. When you buy a house and obtain a mortgage, you’re taking on debt. One of these types of debt is better than the other. Even if you take on different types of loans, you’ll have different interest rates. And it’s important to pay off the ones with high interest rates faster than the low interest rates.

What does this have to do with code? Different types of technical debt carries different interest rates. The key is to quantify the technical debt in your code to determine which ones you can carry and which ones you should address.

How do we do this? The first way is subjective. If you’ve been working in a codebase for a while, you kind of get a feel of what code is messy to work with. If the code is a pain, but you only touch it once a year – that has a low interest rate. If a class slows you down or gets tons of bugs field against it, and someone on your team touches it every week or every month – that has a high interest rate. You’ll get more bang for your buck tackling the frequently changed code than by touching the infrequently changed code.

Subjectivity is, well, subjective. That’s why there are ways to measure technical debt. Wouldn’t it be nice if you had some way to track what files are frequently changed? That’s called source control, my friend. One really powerful tool that can draw heat maps of your changes is called CodeScene (https://codescene.com/). But you can do a quick-and-dirty version of this analysis using git alone.

GIT

The following git command will get you the 10 files most changed in the last six months:

git log --since=6.months --pretty=format: --name-only | sort | uniq -c | sort -rg | head -10

From there, you can find all the commits on the most active file (in my example: buildspec.yml). Hopefully the developers on your project give nice git comments so you can get a sense of what they’re changing and how often.

git log --pretty=format:'%C(auto)%h%d (%cr) %cn <%ce> %s' buildspec.yml

From here, you can do several things. You can get a diff of all those hashes with this command (Make sure you put the OLDEST commit first and the NEWEST last):

git diff 10ce27c^...0dbb003 buildspec.yml

Or, you could even find all the commits of a given function with this command:

git log -G'FUNCTION_NAME' --pretty=format:'%C(auto)%h%d (%cr) %cn <%ce> %s'

I’m sure a git guru could figure out even more fun stats to look at with other commands.

Conclusion

I’ll lave you with a few practical applications:

Leave the code better than you found it. This is based on the Boy Scout rule to leave a campsite better than you found it. Always check in a class cleaner than when you checked it out. It could be as simple as removing whitespace or renaming a confusing variable. If the code gets even 1% better every day, at the end of the year it will be a lot better.

Quantify your technical debt. Either through code analysis tools or simple git commands, find where your hot spots are and come up with ways to mitigate them. If the code is rarely touched, it’s lower priority. Sure, it’ll still be lurking, but it’s not as important as a frequently changed class.

Negotiate for time. Hopefully you belong to an organization that values engineering excellence. But remember, your company’s priority is to deliver value to its customers, not to have pristine code. Your project manager may not care about outdated frameworks or messy code. But they will care if the outdated framework carries a security risk or if the messy code slows you down. An example from my career, a few years ago we wanted to add a third payment processor to our inapp purchase system. I knew the current code was a mess of if/then statements, so my estimate for adding a third processor was 5-7 days. I told the PM if I could have two weeks to refactor the code and implement this processor, any future payment processors would take us only two days to add. I got my time to refactor.

I hope I’ve given you a different perspective on the concept of technical debt.

Happy coding!