There are many ways of categorizing technical debt. Here is just one way. I divide technical debt along two axes: intentional vs unintentional and known vs unknown. And I’ll briefly mention a fifth category that doesn’t fit well with these axes.
Intentional Technical Debt
Technical debt can be a conscious decision, like a real loan. It can make sense to incur technical debt. For example, if you need to find out if a certain feature will be used and is worth developing further. In that case, you might want to implement a minimal version quickly, to measure the interest. If it’s popular, you can pay off the technical debt by implementing it better and then expanding the feature.
This is planned or intentional technical debt.
In the ideal situation, the team and management take an informed decision to take on this technical debt. They should also define how and in what timeframe they plan to address this debt. If they fail to do so, this situation can build up until the project reaches a complete standstill.
Unintentional Technical Debt
Intentional technical debt is the best kind of technical debt and can even deliver business value (for example in the form of a faster release). But in software it can often take some time before we even realize we have taken on technical debt.
This can happen because of poor technical decisions, even when they seemed perfectly fine decisions at the time. Or maybe a developer lacks the necessary skill and experience to identify decisions as incurring debt.
Intentional vs Unintentional
You might think that the intentional debt is the better kind. After all, the decision was made consciously, right? Right, but it makes no difference if we don’t have a plan and timeline to pay off the debt.
Just like a real financial debt, a technical debt is costing you money. Stack up the debts too much for too long, and you’ll have to declare bankruptcy.
Known vs Unknown
Both intentional and unintentional technical debt can be known or unknown.
Known debt is technical debt that the team is aware of. Ideally, there is also an idea of how to fix it. And even better if the fix is in the backlog and has a due date.
On the other side of the scale we have debt that is unknown. This is technical debt that the team doesn’t know exists. This can be because the code doesn’t need any changes and is running fine (but then is it technical debt?). But it could also be because the team doesn’t know there is a better way to approach a problem.
This is a scale, not a dichotomy. The team might know of a piece of code that is regarded as technical debt but maybe they’re not aware how bad the situation is.
A Technical Debt Quadrant
This leads us to the following quadrant:
(the best kind, as long as you don’t let it sit around for too long)
|known unintentional||unknown unintentional|
I mentioned there are several other ways of categorizing technical debt. For example, Martin Fowler also has a technical debt quadrant, splitting up along the axes of prudent vs reckless and deliberate vs inadvertent.
Technical Debt Over Time
In the article I mentioned above, Fowler writes about technical debt that comes from learning over time. The team can write great software with good design that performs as it should, but there could still be some technical debt there.
Over time, a team can learn valuable lessons about what a better approach to writing the software could be. Fowler identifies this as prudent inadvertent technical debt.
I’d like to expand on this and see this as a broader category. Technical debt can arise over time, out of nowhere. Apart from lessons learned by the team, here are some other examples:
- business requirements change making existing code obsolete and costly to maintain, change or remove
- technologies used are no longer maintained or supported (or make it hard to find new developers)
We could put this kind of debt in the known unintentional debt because we usually know of the issue and we didn’t plan for this. But I think it has its own dynamics, enough so that it warrants a separate category.