In the context of software, technical debt is an obligation to pay technical capital later (refactoring code or redesigning a system’s architecture), in return for getting something done now. For example, let’s say that the company SwyftCap has a small program that buys cans of Coke and gets them delivered to the office, and decides it also wants a program that buys cans of Pepsi. Now, instead of changing the Coke-buying program into a generic beverage-buying program, it creates another app with the specific purpose of buying cans of Pepsi, and can finally enjoy the sweeter taste. Sure, the company can now drink both beverages, but it also has to maintain two programs with similar characteristics, duplicating the effort it takes to maintain only one.
If you think this example if ridiculous, you should know that I have personally seen a company developing two projects with the same objective, functionality and operation, where the only difference was the third-party provider. Every time a feature needed to be added to one of the programs, it also needed to be added to the other with very slight modifications, meaning that merging the projects would be even more complicated when it finally happened.
A problem with technical debt is that it is invisible to non-technical people. This is a big one since in many companies the person prioritizing software development work is not technical (project and product managers). A financially savvy executive can look at a company’s balance sheet and see their liabilities as percentage of total assets, and decide if the amount of leverage is looking good, but software design is more debatable. There are no contracts involved. Even if some types of technical debt are pretty obvious to identify for any experienced developer, there can be little agreement on more complex kinds.
If you give 1,000 developers the same coding problem, they will give you 1,000 different solutions. Some will have big errors, some will work but be inefficient, and many will be good enough, but if the problem is even a little complex, there is no way to know which solution is best. There is no best program in software.
Even when applications run well and with few errors,something eventually breaks down: a third-party service changes its interface, a provider goes broke, a programming language stops being supported. Software is alive and needs constant control to run smoothly.
Reducing technical debt reduces total cost of ownership (TCO). Just like preventive maintenance prevents expensive industrial machines from breaking down in the worst way at the worst time and stopping the whole assembly line, software refactoring (and process re-design) reduces risk in exchange for a reasonable investment now, making a lot of business sense. It is a true financial investment: pay a little now (effort) to avoid having to pay a lot tomorrow.
- Ignorance: business owners, managers and decision makers are not aware of its existence or its consequences, hence it is not prioritized the way it should
- Tight Schedules: focusing too narrowly on shipping new features to keep customers engaged, without understanding that many of them seek quality instead of quantity, which is improved by reducing technical debt
- Insufficient controls: not having the right process and standards to make sure that clients get a high-quality product.
- Slow adaptation to change: an application might work well now and comply with the current best practices, but things change pretty fast in the world of software.
- Duplicated code or programs with very similar functions
- Programs with too many unrelated functions, without a predefined scope. Usually seen in monolithic applications
- Supporting and adding code to systems that should be decommissioned
- Slow programs
Solutions to Technical Debt
- Informed management: learn about technical debt. Leverage technical employees and ask them to estimate the resolution time and impact of technical debt. When possible, invest the effort in repaying it. But, as every good manager knows, prioritization involves complex trade-offs.
- Quality focus: this is one of the central points on the book Code Complete, by Steve McConnell. The sooner that bugs are fixed, the easier and cheaper it is to fix them. The same things happens with technical debt.
- Refactor early and often: fixing things as soon as possible will make everything better, and usually make the developers happier as a second order effect. Just like paying credit card interest, better done sooner than later.
- Architecture: use interfaces around legacy systems and take advantage of microservices. This is what Facebook did with code they had from their old core (PHP) and the code they bought from WhatsApp (Erlang). Without getting too technical, the main idea is to build a new system where features are added, which also has the ability to communicate with and control the old system when needed.
- Use established solutions from reputable companies and research best practices