Mon 20th Apr 2026
A Patch a Day Keeps Maintainability Away: My Journey Through Technical Debt
In this article I go into how I found myself in my very first huge technical debt. I detail how solved it by first classifying it and the ways I found of measuring technical debt. I close off with sharing my VSCode extension github link to keep track of technical debt.
Backstory
Earlier on in a certain project I was developing, there was this behavior I had of patching up code for frequently changing requirements - I’ve since come to understand these patches almost always end up being technical debt. Because, all of a sudden a change made a month ago conflicts with another case I wanted to patch up once more.
It reached a point where the patches had built up to where I had to patch earlier patches to make a new patch (tongue twister I imagine). Either that or architect the whole project anew to remove the patches because the project was becoming unmaintainable.
At the time, the current me was looking at the former me on why we brought all this upon ourselves and someone had to take responsibility and yes it is current me - I was in disbelief, I had no idea choices have consequences
To fix this, I started by trying to ensure it doesn’t happen again and on googling about along with some few youtube videos I have the below to share.
Why there is tech debt in the first place and how to reduce it
Usually when developing a feature there is a time constraint in place and this leads to a higher probability of educated guesses that are "falsely correct" - ie not optimized for all cases or not serving a likely edge case. To be fair, these guesses reduce with experience because of knowledge gained with time but nonetheless they are still there.
To put it into some mathematical context picture this graph, of say a unit of “mess” or “tech debt” increasing per unit of time we develop.
As you can see the mess grows with time. It happens much more exponentially in the real setting such that by the time the mess needs to be addressed you are split between either:
- Accepting the codebase as is and continue working with a messy codebase or
- Do a full rebuild because the mess is always going to get in the way of the other features
Now, picture this scenario where you purposefully set a fraction of a unit of time to clear the mess.
With the illustration above, the unit of “messes” never goes out of control. Also, at a micro level the speed of development seems reduced but the overall(macro) speed is improved. Unlike the first option where the speed is fast but it can then come to a screeching with a big mess halt such that the overall speed gain is near zero.
To summarise the graph, the second graph has a “clean as you go” type of approach and this is better because:
- Fewer and smaller “messes”
- Speed increases since less time spent working on previous “messes”
- Better quality work
- No time will ever be needed to prioritize tech debt over features
Apart from the simple method above some other ways of trying to avoid technical debt is:
- Test driven development - write tests first to prevent poorly designed code from entering the system in the first place
- Pair programming - two sets of eyes can catch shortcuts before they become permanent debt
- CI/CD pipeline - automated checks to prevent tech debt from reaching production
- Following design patterns - these are consistent architectural approaches to reduce inadvertent debt
After reviewing how I got there and how to avoid getting the tech debt in the first place, so as to avoid a repeat cycle of the same, it was then time to get myself out of there.
Mapping out the technical debt
To get myself out of there I needed to know the size of the hole I was in and to do this I had to find a wat to quantify the technical debt. First, I had to classify the debt in the code. A great way I found to classify most of the work in the codebase using Martin Fowler’s tech debt quadrant pictured below.
From this quadrant - I developed a VSCode extension to actually mark a certain function or piece of code when I do any action leading to technical debt. You can get the vscode from this github link: https://github.com/xlvisben/technical-debt-scanner
This provided a way for me to weight the debt and then I had to quantify and I go into these methods below.
Methods of quantifying tech debt
- SQALE (Software Quality Assessment based on Lifecycle Expectations) - an open-source, tool-independent method used to evaluate and manage technical debt by analyzing source code against quality requirements. It provides a standardized framework for calculating the cost (effort) to remediate technical debt, enabling teams to prioritize refactoring and track debt trends over time
- Technical debt ratio - it follows the formula:
Tech debt ratio = Remediation cost(cost to fix)/Development cost(Cost of development)
eg if it costs $1000 to fix but the cost of development is $10000 its ratio is ($1000/$10000) * 100 =10%
Generally anything below 5% is good, 6-10% is moderate and 11-20% needs a serious look
- Checking the impact, fixed cost and spread(how much of the code base is affected) - you’d want to prioritise the highest impact which is not too hard to fix and spreads the most.
- Cyclomatic complexity - its a measure of code complexity and decision points
- Lead time - the time it takes from commiting code to production, longer lead times usually indicate a large tech debt since a portion of time is spent trying to fix other issues instead of pushing features to prod.
- Code churn - this refers to the frequency of file change, if a file is changed alot of times that means the tech debt is high
- The “PAID” method of measuring which stands for:
- P → Performance impact of the app
- A → Architectural importance - if it is core to the system
- I →Integration complexity - how tied it is to other systems
- D → Dependency - if a change breaks a bunch of stuff
- Pareto principle - find the 20% of the code base causing 80% of the issues. Also with this method there is a matrix to it which helps.
The above I took a better part of 3 weeks to figure everything out. Frankly, I am not quite there yet when it gets to tech debt management but I believe I am getting there. Most of the times I usually take time to let my mind breathe after an initial feature development so that rarely the first implementation ever gets pushed to prod. This gives me time to have a good reflection but of course I don't do it to a point that it delays feature delivery.
Hoping you got a good read from this one, please do share any feedback below. Also, check out the VSCode extension on this github link to mark the snippets that you want to revisit later.
I like to think of the VSCode extension like Julius from Everybody hates Chris staring at me. Every time I see that list in my activitiy bar, I just imagine Julius telling me: "That is $4.00 worth of refactoring you're ignoring!" or "You think that nested IF-statement is free? That’s 20 cents of electricity!". It serves as a constant, comedic reminder that code debt is actually building up to real financial debt.
Resources and references
I used the below videos and article to come up with a good chunk of content on here.