The term "Technical Debt" was coined by Ward Cunningham as a metaphor of financial debt whereby you're paying later for decisions your making now (with interest of course). Often times metaphors and analogies are used by technical folks to describe occurences such as technical debt to those that aren't in a technical role. It can make it easier to understand and describe a problem without using too much in-depth detail. Although when it comes to using this term, it is often used as a catch all for system improvement and isn't fully understood.
Defining technical debt
There is a lot of information online about what it is. There are even entire websites devoted to the subject. As a baseline, it's trading off some part of the project now in order to meet an immediate need. Maybe the project has to ship soon, so you don't take time to write tests or documentation. Perhaps a decision was made to have less meetings to discuss ongoing project progress in order to save cost, thus leading to assumptions being made and a lack of shared understanding. Both of those things may help now, but will hurt in the long run.
Another way to describe technical debt is to think of it as a loan. Martin Fowler describes it well in his post about it:
"Like a financial debt, the technical debt incurs interest payments, which come in the form of the extra effort that we have to do in future development because of the quick and dirty design choice. We can choose to continue paying the interest, or we can pay down the principal by refactoring the quick and dirty design into the better design. Although it costs to pay down the principal, we gain by reduced interest payments in the future".
A lot of times this debt is never paid off. It then becomes a reason used when giving a higher cost for new work that builds on top of some older work. Over time, any task becomes arduous and every feature takes twice as long to complete for a project containing technical debt. Estimation meetings also become a tough exercise laden with squinting, chin scratching developers and long pauses following each question. Technical debt is often discussed between technical members of a team, but it is important that the idea be shared amongst non-technical staff and project stakeholders as well. This is to better appreciate all that can happen during the lifecycle of a project and how it affects the future as well.
Why does this happen?
There's two areas where this might be happening. One is in the initial development and the other during subsequent work post-launch. Technical debt often becomes more apparent in the latter, especially as time goes by. Usually once it is recognized, it becomes a difficult problem to address. Often times we try and take advantage of a change request or new project from a client to work in these little fixes to keep the house standing so to speak. It's when you start needing days to fix past problems that it really becomes difficult. Imagine an estimate is requested to implement a new feature. You could build in a line item that reads "pay down technical debt" or "refactoring" or maybe something more specific than that. Either way, it ends up becoming a tough sell.
Why is that? Well if you take the point of view of someone actioning the request, their focus is on a tangible deliverable. Priority can rarely be given to something that is basically seen as background work to those less informed. Though it can be interesting to think about this from a non-technical standpoint. If work was being done on an old house, the client would consider that it is old, and some initial support work might need to be done upfront before actioning a new addition or having other work done. But in the software world most people are dismissive or simply unaware of these kind of background tasks. After all, you can't see or touch them and it's not like a house is going to fall down if they aren't taken care of first.
Sometimes it is recognized as a problem by all involved parties but something that just can't be actioned. An extreme example of this is dealing with a decade old system riddled with issues that still basically works but can't be completely rebuilt or fixed due to budget or other restrictions. Thus continues the downward spiral of patches and quick fixes to keep it running while it further sinks into the quicksand that is technical debt.
The other footnote to why it happens is in the initial developer choice. Often times the approach is to seek out the cheapest solution possible. This might involve a freelancer or someone who is vaguely familiar with the requirements but wishes to win the work. The client then ends up going with that cheaper option as it appears attractive at the moment. However, in the long run the project can potentially become overwhelming for the initial developer(s) to manage and is likely the case for another vendor to pick up the work from that point. Ultimately when shopping around for someone to build your project, it is advised to consider what the "Total Cost of Ownership" looks like. This means to appreciate that there is more value to a project than initial cost.
Technical debt in disguise
The other example we'll give is not so much about technical debt, but something that can just happen over time that is dealt with in a similar way. We'll mention it as it sits in a grey area and some would consider it is in fact technical debt. It also happens often and is dealt with similarly. Imagine an average website that has even a modest feature set. The project starts off great, but over time change requests come in tweaking this and that, or a reasonably sized feature gets added on which may or may not impact some existing functionality. Assuming this happens over say 3 years, that leaves a lot of opportunity for things to change:
- Both the client and vendor have lost sight of what's been added since the projects inception.
- Personnel changes have happened on both client and/or vendor sides
- Little or no documentation has been written along the way.
- A bunch of small tweaks have been done, leaving hesitation on both sides about removing anything for fear of not knowing what it does
The above isn't really technical debt. It's not to say there was a concious decision to get to this state. It's rather just a side effect of the above variables over time. Each small request never looks scary on its own but when you consider the full timeline of changes you can appreciate how you'd end up with a bloated system with many changes, some of which lay dormant behind more modern features. In this way it becomes a similar exercise to addressing technical debt. You need to clean house as a result of time.
What can we do about it?
Try and keep documentation about what is changing with a project. It's not enough to have knowledge holders on a subject. Being able to point to a place for reference is valuable for anyone, even for use by the original developer 3 months later!
Similar to documentation, this will help raise red flags if anything stops working. They also serve as documentation in a way, outlining what something should do.
Having multiple eyes on the project
Making use of a pull request workflow so others can lay eyes on your work. Alternatively, ask questions amongst the other developers on your team before tackling a task or employing pair programming can help spread shared understanding.
Taking small steps to refactor over time as needed and avoid buildup.
Taking an hour to install an update and test it as they come out is far better than dealing with a year's worth of updates all at once. It becomes harder to address once you slip further behind each update and your platform drifts into obsolescence. Also, if you see a small opportunity to address something, you should bring it up to the client before it ends up needing its own line item on an estimate worth 2 days! It can then be a much harder sell as mentioned above when it gets to that point.
Talk about it.
Don't be afraid to discuss any impact existing work is having on the project, or any future considerations you foresee. Addressing technical debt is just as important as doing the work itself.
Lastly we'll say hire good developers, as they will most likely be cognizant of all the above points.
All this being said, there isn't a way to fully avoid technical debt. There is always going to be new technologies coming out that users will want and there will always be different needs that have to be met depending on the business or personnel involved. These things are inevitable. In 2007, no one knew that soon everyone would need a responsive version of their website for mobile viewing. Also, we're now seeing more accessibility awareness and requirements that are needing to be met. The best we can say is to be aware of the current state of any of your projects. Even if there isn't anything wrong yet, a little preventative maintainance can go a long way in keeping all parties involved happy and with a peace of mind knowing that the next iteration won't contain unnecessary surprises and extra cost.