Understanding technical debt
In the creation of a web site, there are several groups of people who participate: product managers or marketing representatives who are responsible for defining functionality and design, user interface designers who create the actual visuals, and the developers who are responsible for implementing the final product. Of these groups, developers tend to get a reputation for being a bit touchy and grumpy for coming up with reasons why things can’t or shouldn’t be done. The reason why this happens is because the developer is, consciously or subconsciously, trying to manage the project’s technical debt.
Technical debt, or tech debt for short, is quite simply the amount of technical work remaining on a project. It’s something that is hard to quantify, typically existing in one or more developer minds at any given point in time. There’s the initial debt of hours or days to completion which is usually the estimate delivered to the manager. After that, every technical decision that’s made comes with some sort of tech debt.
Deadlines rarely align with the amount of time needed to complete work, and so technical compromises are made along the way. There’s a short-term tradeoff to get something working initially. The developer knows the lifetime of the solution and accepts that he or she will have to go back and create the longer-term solution later on. While those looking in from the outside might consider this to be sloppy engineering, it’s actually what allows products to be released on time. And also how tech debt accumulates.
Tech debt doesn’t show up on any product roadmap and so developers frequently try to address it as they’re working on other features. In some organizations, a savvy manager may be able to buy the developers some time pay down their tech debt, but that is the exception more than the rule. Those making business decisions typically don’t like giving time for paying tech debt because, in their mind, the work isn’t resulting in any new features. Why should they give you time to work on something when the end result isn’t a new feature?
In the worst case, tech debt can accumulate to the point where the web application is destined to fail. A classic tech debt issue is scalability. Initially, the goal is to get the web application up and running so that anyone can use it. Decisions are made to allow that to happen. But an app that can handle 100 users isn’t built the same way as an app to handle 1,000,000 users. In the back of the developers’ minds are a list of things that need to happen in order to scale out: hit the database less, implementing several layers of caching, reduce the size of responses, figure out a faster way to process orders, and so on.
Just like monetary debt, tech debt is best dealt with before it gets too large and overwhelming. Regularly tending to tech debt is a process I like to call code hygiene. If you don’t go to the dentist for ten years and then finally go, chances are you’ll be in for a nasty surprise by not practicing proper dental hygiene. Code hygiene is the same. Keeping on top of your tech debt means regularly going in and addressing what you can with the time available. Good code hygiene means regularly:
- Deleting unused code – I always say that any day you can delete multiple lines of code is a good day, and one where you earned your paycheck. Unused code shouldn’t be allowed to live in a codebase because, just like bacteria, all it needs is one opening to cause a big problem. If you suspect code isn’t being used, verify and then remove it. Don’t make a note to do it later, thus creating more tech debt, do it immediately. Less code means less to go wrong and faster builds and deployments.
- Refactor code – The time to refactor is as soon as you notice a problem. Don’t allow sloppy or bad code to remain in the code base. Code has a way of duplicating itself without warning. New developers come in looking for an example, find bad code, copy it, and now you have two pieces of bad code instead of one. That’s more tech debt. Make sure that all code you check in is worthy of being copied to prevent future tech debt. When you’re building off of existing code, make sure to include some time in your estimates for refactoring.
- Rewrite code – It’s rare for developers to be able to rewrite something from scratch, but it’s a necessary part of code hygiene. Good code should be able to run for five years without being rewritten; bad code needs to be rewritten as soon as possible. You should always try to refactor first, but if that fails, it’s time to rewrite. Making the business case for rewriting is difficult, but if you can tie the rewrite to a new feature, you have a better chance of getting the time.
Technical debt is a part of every project, and one that needs to be better understood by all parties involved. Building time into every release for code hygiene is a good idea and can take many forms: bug bashes, where everyone takes a day or two and just works on bugs, engineering-driven features, which are features of the platform rather than end-user features, and code reviews, where engineers inspect each other’s code, are all good practices to have on the team to ensure tech debt doesn’t get out of control.
Disclaimer: Any viewpoints and opinions expressed in this article are those of Nicholas C. Zakas and do not, in any way, reflect those of my employer, my colleagues, Wrox Publishing, O'Reilly Publishing, or anyone else. I speak only for myself, not for them.