In some ways, technical debt is similar to financial debt, where you prioritize purchasing an item now instead of waiting and saving for it. Technical debt happens when we need something now or very soon, so we do everything in our power to get it. This includes making coding or design decisions - that we know will have to be addressed sometime in the future - to get what we want quicker.
Basing on the things we have learnt so far, we can now move on to discussing the techniques of debt measuring and their use in the prioritisation, monitoring and prevention of technical debt.
Throughout the post, I will be making reference to the previous article, so consider reading part 1 for a better understanding of the topic, if you haven’t yet.
How to properly identify and measure Technical Debt
The complexity of the topic lies in the fact the tech debt level is not easily measured. Therefore it’s not trivial to prepare some slides for the steering committee meeting and demonstrate it with tables and graphs containing sheer numbers. Though that doesn’t mean that there weren’t any attempts ever made to automate the technical debt measurements and quantify its various levels.
Technical debt measurement at the codebase level
Static analysis tools
There are static analysis tools that could provide you with some valuable input. For my beloved Ruby programming language, there are tools like Skunk, Reek or Rubocop - all of them could be used to run through your codebase and generate the report based on its findings.
The caveat: as with any static analysis, the reports should be taken with a grain of salt, and the best approach is to use the plain numbers they provide as a basis for a qualitative analysis of the technical debt problem you may have in your web application.
The aforementioned tools put focus mostly on the code complexity and structure in relation to the other factors like code coverage. However, there are also other criteria you can measure your web application code. These include elements like code churn and code ownership.
The code churn metric can be aliased as a "quick fixes'' metric. I remember working for a client from the USA, who had been developing an e-learning product. We've been using Agile/Scrum and during one stand up, when I've been asked for a status of an issue I said something like "that was a quickfix". My statement caught the attention of a lead developer, who immediately followed up with a question "was that a fix that was quick or a quickfix?"
It's easy to understand where that lead developer was coming from. The code churn resembles the number of times a particular line has been touched by a developer, who has deleted, replaced, or rewritten the code in question. The code churn is something that you can expect for new functionalities, however, if you continue to see it for some already settled features, then it may indicate that you may have problems with quick fixes inevitably introducing technical debt you'll be paying off in the future.
Hence, in that standup situation I described, I've just been asked by a lead developer if I chose to introduce a technical debt for some reason, and eventually if we need to do something about that.
The code ownership is similar to code churn, but instead of counting the number of times a particular line of code was touched, you count the number of how many different people were tasked with applying changes.
Programmers are not robots, and while each of us tries to follow coding best practices, we may come up with different approaches and follow different visions of solving the same problem. Hence, with many architects behind the developed solution, the chances of getting a Big ball of mud get higher than in a situation where there was a proper code ownership strategy (task delegation) for the development process in place.
It's a typical situation when the web application or its particular part haven't been developed by one team (software service providers have been changing over the years, or there was no concept of a developer team at all).
Technical debt measurement at the project management level
Technical debt measurement can be also taken at the higher level, revolving around project management. You can for instance make a retrospective and analyse your current development cycles and compare it to the historical data. If it happens that your CI/CD approach allowed for shipping code each day / every few days and nowadays it happens once in a sprint (or less frequently) then it’s worth investigating the cause.
Also, the rule of thumb is: trust your developers. Imagine that you’re planning a sprint and your usual approach is to collectively decide about the incoming sprint assignments. And it happens whenever “the functionality X” is on a table, there are no volunteers; developers become defensive and you can hear a snarky remark or a giggle while discussing who should pick something up - that’s a good opportunity to ask your team what’s causing that.
Also if you hear that “Joe should be assigned to functionality X task, because only Joe…” may also be troubling for many reasons, and one of them may be technical debt. If something requires an extraordinary skill to work with, because it’s not SOLID), then clearly you have amassed a lot of debt to pay off.
Finally, the amount of bugs appearing now vs particular development periods in the past is an indicator on its own. That can also be a retrospective topic.
What is the actual price of technical debt?
Now that we have gone through the challenges of the technical debt identification and measurement, a few words on the actual cost in money, because that’s usually a baseline for decision making for people who are calling the shots when it comes to paying the technical debt off and when.
One obvious thing is an attempt to estimate the identified workload in terms of development time. But usually, it’s also beneficial to understand the overall future cost of technical debt. Here the Technical Debt Ratio (TDR) comes in handy. It is a relatively simple equation of:
In the given formula the remediation cost stands for the cost of fixing the software system, whereas the development cost is the cost of building it from scratch. The result is a percentage you should consider for any new development, as an extra cost of building and shipping software. Such a percentage should also allow for making informative decisions about the next steps in software development and is good to bring up in meetings with stakeholders.
What steps to take to deal with technical debt? Prioritisation, prevention and monitoring
Now that we know how to identify and measure the technical debt (including the cost) we have a whole spectrum of choices where it comes to addressing the technical debt, short and long term.
As we have an idea of how much technical debt there is, we can try to quantify the cost of paying off that technical debt, as well as the cost (interest) incurred on any new functionality or amendment in the system, assuming that the technical debt level remains unchanged.
Hence, we can focus on the prioritisation of the particular technical debt elements and come up with the technical debt repayment schedule.
We can also work on improving our monitoring processes in order to prevent adding more technical debt, as having the debt identified we understand our situation and it might be the case we just can’t afford to add any more debt. Or we come to a decent conclusion that in a retrospective we did regret situations, whenever we added a technical debt in the past.
Because technical debt shares some similarities with medical science, where it’s a known fact that prevention usually costs far less than the actual treatment.
With the level of cruft measured, there are plenty of good ways on how you can move on with the technical debt. However, it is worth noting that the baseline for all these opportunities is open, transparent, quality communication and tracking the technical debt, ideally on an ongoing basis.
Yet, the software craftsmanship has to sometimes deal with situations where the PM or a team leader is pressuring developers and asking for impossible commitments on the scope delivery so some kind of arbitrary deadline is being satisfied. And such situations origins may trackback even as far as the selling the service process, where the impossible deadlines were promised in order to close the deal.
It may be the case that you can’t prevent your salespeople from promising impossible things to your customers or there is another process in your organisation that lets such things slip, but what you could do is to at least try to counter the aforementioned with other processes that allow for debt paying.
And you can start by ensuring you have an environment where developers are transparent with you in terms of what kind of shortcuts are required to be made in order to fit the imposed time constraints.
Paying the technical debt here would mean starting with strictly tracking these aforementioned shortcuts and reserving some time in the roadmap/schedule to get rid of that debt. After all, paying the technical debt starts by recognizing it.