Technical debt it is the difference between what your promise and what you deliver in software development. It is the difference between what is quick and easy upfront and what is efficient and scalable in the long run.
Shipping ‘good-enough’ code is like taking on financial debt; you borrow some money and you pay it back with interest. When you ship buggy or messy code you are borrowing time and you pay it back with interest.
Every minute you spend working on not-quite-right code accumulates interest as extra development work. Wasted development work. This is what we call technical debt, the gap between where your code is and where it should be.
Most companies create technical debt all the time.
What is technical debt?
We can categorise technical debt under four key concepts.
Reckless Deliberate “ “We don’t have time for design.”
You take shortcuts to meet deadlines inflicted by clients who have no idea how long things take.
Prudent Deliberate “ “We’ll ship now and deal with the consequences.”
You are exploiting a market opportunity. Sometimes being first to market is more important than releasing a perfect product, and first-time consumers tend to be more forgiving of initial faults. Refactoring bugs prior to your next product update is crucial to maintaining market lead, and your consumers will be less likely to migrate to a superior competitor’s product.
Inadvertent Reckless “ “I’ve got no idea what I’m doing.”
If your programmers are incompetent or inexperienced, they are probably unaware adding and removing code has consequences. Any debt incurred is unlikely to be addressed and your product probably will not survive the market.
Inadvertent Prudent “ “Now we know how we can do it better.”
New knowledge and experience post-release allows you to reflect and understand how you can improve future products.
Where does technical debt come from?
If you fail to nurture effective communication channels with your clients, then you may find yourself faced with unrealistic deadlines. When early and continuous deployment takes priority over design and excellence, technical debt can accrue.
Clean, well-designed code will allow you to implement future iterations and innovations with ease. Larger companies generally prefer slow and steady, but most startups need to work faster to survive. Technical debt and dead software holds businesses back.
Why is technical debt bad?
Mounting technical debt impedes velocity as you attempt to work with a sluggish, bug-filled product. This makes it monumentally harder to move from an immature definition of done to production ready code.
Refactoring your code is crucial to resolve issues with architecture, structure, duplication, test coverage, potential bugs and complexity.
Imagine your family is coming to visit. To meet the “deadline” of their arrival, you shove everything into that cupboard so all your messy miscellaneous pieces [lines of code] are out of sight and your house [product] looks clean. Eventually you may need to find something [fix a bug] or move house [create a new feature]. The more stuff you pile in there [lines of code you “quick fix”], the harder new implementation will be.
Repaying your technical debt, one line at a time
While categorising your debt does not make it magically easier to handle, you can have productive conversations.
There are a few key steps you can take to make things easier:
- Keep a backlog. Everyone will be able to see what is happening in your codebase; debt is visible, quantified and its removal prioritised.
- Maintain slack time for refactoring. Do this incrementally through pair programming, code reviews, continuous integration and automated testing.
- Implement coaching and training for new team members.
- Do cost/benefit analyses. Reflect on how much time it will take to fix each piece of ‘debt’ to make the best decisions for your company.
- Refactor, Refactor, Refactor!
Your approach to technical debt should be clearly articulated and negotiated to balance better business outcomes during app development. You should always try to leave a codebase in a better condition than how you found it.
The best architecture and designs emerge from self-organising teams who refactor regularly, reflect on how they can be more effective and then tune their behaviour accordingly.