Have you ever noticed that as time passes programming projects become slower and slower? Developers seem reluctant to touch the codebase, features and bug fixes take longer and longer. And this slowdown is very gradual/ Heck, whenever they start a new project it seems to eventually start happening to those projects as well. The answer is often quite simple: your projects are suffering from technical debt.
Technical debt is commonly used as a metaphor in software projects. This “taking shortcuts to ship code faster” is similar to using credit cards to pay for things. We can buy more now with credit cards, but we have to pay it back with interest. In both cases the more we borrow, the harder it gets to pay it back. Just like with credit cards each future “transaction” or feature will have to pay back part of the technical debt. The debt and interest make any changes to the codebase harder and trickier to do, slowing down development.
Technical debt is just like credit card debt
Just like with credit card debt, you can either pay the minimum or pay more to reduce the debt. In programming, this usually takes the form of doing the bare minimum to make the task complete. Or in the form of taking time to clean up and improve the surrounding code. The problem starts when the minimum payment is not enough to cover the interest. So no matter how long you pay, you’re never able to pay it off. You have to increase the amount you pay or borrow less. Technical debt if mismanaged can also become a case of “gets credit card to pay off credit card debt” rabbit hole.
While there may be someone specific to blame for technical debt, usually it’s a mix of systemic and environmental factors. It will never be a simple root cause for technical debt. More often than not it’s more similar to gaining weight and overwork burnout. If you started doing a second breakfast last week you might pinpoint it as the cause of sudden extra weight. You didn’t change meal habits and suddenly you are heavier than a few months ago!
This means that extra weight is a symptom of a more systemic problem. And fixing it will require some reflection, planning, and discipline. Just make sure you don’t fall into the trap of just doing instead of thinking first. Declaring “two weeks of only cabbage!” won’t stop you from regaining weight after you stop the diet. Incidentally, both the metaphorical and literal interpretation of the cabbage policy won’t work in software projects. Unless your team is automating a cabbage farm, in which case it’s cabbages every week!
What can help fuel technical debt?
Now let’s take a look at a few common patterns of behavior that can increase the technical debt of your projects. While they may not be the ultimate debt stoppers, they are nevertheless a good starting point if you want to reduce technical debt and increase the long-term productivity of your teams.
Perpetual rush and crunch
You may have noticed that a lot more seems to get done in the last few days before a deadline, important demo, or when a braking bug is found in production. While this is perfectly fine if it doesn’t occur all the time. If your teams get caught in a continuous cycle of light work followed by a rush to finish by the deadline, you might have a problem.
In some industries like accounting and auditing annual periods of crunch are normal, but if often repeated in software development it can be quite harmful to the long-term team productivity. It leads to burnout, which affects both productivity and staff turnover. And usually, the first victims of haste are due diligence, documentation, and sanity checking. And skipping them quickly leads to unreadable, unmaintainable code.
Any team caught in cycles of rush and crunch will in the long term become ineffective. And now back to technical debt, even if you change your burned-out team, the debt still stays in the codebase. If you find your team caught in cycles of crunch you might be understaffed, your goals might be overambitious or you may be so deep in a technical debt hole that your team is unable to effectively complete tasks set in front of them.
Evaluations/rewards based on task compilation speed
If the programmers are evaluated based solely on the amount of work they do, or the amount of code they produce you are likely to end up with low-quality code. We won’t go into too many details here, but instead, simply point you to two great articles on this topic:
Only approve work on features or critical bugs
If you never allow your teams to work on improving the codebase, it will never get improved. Two common ways to do this are to enter allocating some time for the task of implementing a “leave it tidier than you found it” policy:
- In the first approach, you simply ask your team “Is there anything you’d like to change in our codebase to make it easier to work with in the future?”. And then simply add those tasks to the task list and allocate them when appropriate. For instance, in many places, Christmas/New Year and summer holidays season tend to be low in productivity and thus perfect for such endeavors.
- The second approach works by always asking your team to take a few extra hours on a task to make sure the code it touches is cleaner and nicer. It will slightly reduce your productivity in the short term, but in the long run, starting from a good codebase will greatly reduce the time it takes to complete a new task.
Code gets pushed without feedback
One of the few golden standards in software that everyone agrees with is not allowing code to become mainstream until it’s checked by at least a second pair of eyes. On one side this stops a lot of mistakes and bugs from reaching production while also forcing people to write code in such a way so that it’s understandable by other programmers.
This sounds like an obvious thing, and every programmer you ask will tell you that code should be written to be understandable by other people. But many developers won’t do it until there is some external pressure for them to do it.
Prototypes are good enough for production
The problem with prototypes is that during a demo they should be indistinguishable from the final product. Prototype airplanes fly! So if it already flyes by spec, why is it so hard to polish the prototype into the final finished thing?
Well, the problem is that prototypes focus on one or a few aspects of the final product. And you basically slap everything else together with metaphorical (or actual) ducktape so that you can prove that the concept in question works. While some of those “other” components might stay the same in the final product, some will require complete redesign or will be built from the ground up.
And if you simply try to rush the prototype to production, you will generate a lot of technical debt and either release a half-working product or you will end up with years of delays to get it to a working state. A notorious recent example of this is the Cyberpunk 2077 Game release which was both delayed by few years and released in a barely working state. The estimated damage this caused is in 100s of millions of USD.
Further reading on technical debt
This article is a part of the series of articles on the topic of technical debt. Check out the previous article that focuses on technical debt from the developer’s perspective.
For more relevant articles check out: