I was working at a startup about 5 years ago when I was introduced to the concept of Technical Debt, a term coined by Ward Cunningham to explain the amount of necessary future rework created when a development team takes shortcuts to rush a product to market. While our own product barely made it to Minimum Viable Product stage, I remember thinking that the concept accurately described nearly every software project I’d worked on up to that point.
Cunningham spoke about the need to refactor hastily constructed code, but we use similar jargon to refer to other similar problems in long-running projects: cruft, code rot, software decay, entropy, jank, dependency hell. And while all these terms aptly describe the qualities of lengthy projects, none really address the issue quantitatively.
I can’t remember the last project I was on where the Dev team didn’t want a full sprint (or more!) to dedicate to paying back technical debt. I also can’t remember ever being on a project where we could convince a client to pay for a sprint that had no obvious deliverables. The qualitative argument is that those shortcuts we took earlier will cause decreased productivity going forward, but qualitative arguments rarely lead to budget line items, and the debt continues to accumulate.
I once had a client who would contact me every 3-6 months for some small work on a web app which I’d built for them using Ruby on Rails. Over the course of several years, technology changed dramatically: there were OS updates to the local development environment, security and feature updates to the Rails framework, and successive versions of Ruby and the various third-party gems we used in the app. These collective changes meant that every time I sat down to do what should have been less than a week’s worth of work, I had a pile of major technical challenges that had to be resolved first. The regression test harness broke. Small changes became major hassles. On a time-and-materials contract, this translated into real money for my client, who became less and less interested in regular maintenance of the app – and the cycle continued.
Fortunately, you can quantify most Technical Debt if you document it as it accumulates. If you have a good ticketing system (we’re using JIRA here at WillowTree), you can simply create a ticket to track each known refactoring or dependency change, along with a rough estimate of the complexity (i.e., story points) or staff-days required to implement the change. On my current project, we are now adding JIRA stories as one output of code review for new features – the reviewer identifies improvements that could/should be made to the code, but aren’t strictly necessary, and these changes get logged as a JIRA task with a guess at story points. The project manager (that’s me) can then coordinate with Dev and the client to figure out if/when to tackle those tasks. As long as we stay on top of the backlog of items, we’re unlikely to see the same kinds of staggering Technical Debt Bills that can accumulate. This also makes it possible to pay down the technical debt in pieces over time.