November 02, 2020
Some time back, I was working on a project where it felt like the timebomb of technical debt was exploding in our faces. We couldn’t refactor the whoositz because of the whatsitz and when we asked about the whatsitz no one knew about the whatsitz and how it exactly worked with the whoositz and there certainly weren’t tests for it. When we notified management they replied, “We’re in a build the plane while flying situation, how can we get this out now without doing a big rewrite?” It was pretty clear how the technical debt had amassed.
This launched me on a bender exploring the concept of technical debt. I knew what technical debt was, or rather what it felt like, but I didn’t have a great way of explaining it that wasn’t purely subjective. “Code smells” are a great tell, but if “Code I don’t like” is the bar to qualify as technical debt, you’ll be refactoring the entire project every time you hire a new employee who has big opinions.
After some searching, I was pleased to find this short video by Ward Cunningham, the software programmer who originally coined the phrase “technical debt”, where he explains the concept a bit further…
“If you develop a program for a long period of time by only adding features but never reorganizing it to reflect your understanding of those features, then eventually that program simply does not contain any understanding and all efforts to work on it take longer and longer.”
I like this definition that the problem lies in “never reorganizing [the code] to reflect your understanding.” In a go-go-go product cycle, that loss of understanding begins to create problems that have literal and figurative costs. A general sense of confusion builds and builds. The developer economics are fairly simple to quantify; either you slow down and pay someone to refactor and document the code after every major iteration, or you pay every developer who works on the project until the end of time to stare at the code for a few hours and wonder what the hell is going on. That dumbfounded staring at the codebase compounds over time. Organizationally, you pay in velocity and turnover; talented people are going to leave after a few rounds of bullshit.
Knowledge management is so important in organizations, but they rarely undergo that critical step of reorganizing to reflect the current understanding. Need evidence? Take a look at your nearest corporate wiki. I can almost guarantee it’s a mess because most companies should never have wikis. Successful wikis, like Wikipedia, are powered by an army of editors and most organizations will never prioritize that much time or content strategy. Poorly managed knowledge leaves organizations with the memory of goldfish. I can’t tell you how many new product initiative meetings I’ve been in where no one remembers the meeting about the exact same thing from two quarters ago. It’s like Groundhog’s Day, but you’re having the same meetings over and over.
One thing I like about Cunningham’s understanding-based view of technical debt is that it leaves room to justify a big refactor when necessary. If there’s been enough organizational turnover or enough feature creep in a product, then maybe doing a rewrite is the best option so your team has a collective understanding of the code. You can’t expect people to be productive in something that was a culmination of rushed code, poorly understood requirements, and shortcuts made by people who no longer work there. At that point your technical debt balloon has popped, you are in possession of a toxic asset, and it’s time to pay the piper. And perhaps, with some agreed upon principles, you can find ways to cheat entropy or build technical credit instead of accruing debt or endlessly chasing the new shiny.