Technical debt has become a widespread metaphor used to communicate the need for refactoring code — and it’s one that fills developers with feelings of dread.
Ward Cunningham, one of the signatories of the popular Agile Manifesto who coined the term, compared it to financial liabilities — once engineering shortcuts are taken to release a product feature, debt is incurred and interest is paid in the form of a decrease in team productivity.
But like every trope, technical debt tries to encapsulate many, often conflicting concepts in an easy-to-grasp explanation which can quickly become unhelpful. The idea of interest repayments affecting the ability to deliver to your customers becomes an excuse for missing deadlines, employee dissatisfaction, and user experience compromises.
Conflating multiple issues under one umbrella leads to an inevitable failure to determine effective solutions.
Without full understanding of what is and isn’t technical debt, all we have is a range of pains and symptoms without a grasp on underlying impediments or possible panacea.
What isn’t technical debt
Several distinct types of engineering tasks and organizational issues are often lumped under the definition of technical debt — but at their core they’re a natural part of the programming lifecycle.
1. Maintenance work
Both software and design are like a garden — they have to be continuously maintained to remain in good condition. Different technologies and tools come with various maintenance costs, whether it’s regular data migrations, dependency updates, addressing security vulnerabilities, or design refreshes.
There’s nothing alarming about this type of work as it’s crucial to ensuring smooth product operations, thus it shouldn’t be categorized as technical debt. Some tasks are mundane, and that’s totally fine — we won’t be creating life-changing software every day.
2. Lack of process
Multiple types of issues are categorized as “technical debt” when, in reality, they’re more like process shortcomings. A few good examples in engineering might be the lack of a reliable deployment process or enforcing code formatting. These hurdles are entirely preventable by employing suitable tools and architecture thinking.
The symptoms of those pitfalls might look like technical debt, but they aren’t. Failing to automate can cause a perception of badly designed software and might be mislabelled as debt. Automation and relevant documentation are crucial for project longevity and team productivity. When we establish relevant practices, we can focus on what matters: creatively and confidently fulfilling the mission promised to our customers.
3. Quality compromises and questionable design decisions
Widespread in startup culture, the "fake it till you make it” MVP (minimum viable product) approach and aggressive deadlines often lead to releases that don’t quite live up to our standards of excellence and customer usability.
While there’s value in good enough and proof-of-concept solutions, we do have to be conscious of the benefits and drawbacks of that approach. We assume there’s always going to be time to come back — to refactor and fix the compromises we’ve made — but in reality, they might take a much longer time to resolve than we’ve anticipated.
When shortcomings are left unaddressed, it can create a culture of mediocrity and chaos. Low standards and poor-quality products don’t inspire excellence; they promote hopelessness, and it’s hard to feel empowered to address a vast amount of compounding difficulties.
Forsaking quality and standards, for any reason, isn’t technical debt — it’s a conscious choice.
4. Contributor frustration
We are opinionated in the ways we choose to set up our workspaces, which tools we use, and what technologies we find appealing. Those choices often make us productive and enhance our craft. But when we’re forced to work within a different ecosystem, frustrations might emerge.
It’s challenging to alter the way we work, especially if our tools feel dated. Older technologies and processes become the obvious reason for productivity slowdowns and technical debt. “Why aren’t we using the newest technology?” becomes a frequently asked question, especially in the current climate of over-saturation with SaaS services and tools.
In some cases, it’s entirely valid to explore new products and technologies, but in others, our striving for novelty becomes the driving factor for abandoning perfectly suitable solutions under the umbrella of technical debt.
Just because a technology is a few years old and possibly frustrating in some cases doesn’t mean you’re in technical debt. We need to stop projecting our annoyances as pitfalls of technological or design choices.
5. Outgrowing solutions
Architecture and processes established in the context of an early-stage startup, catering to dozens of customers, won’t be suitable when employing hundreds and serving thousands. Our technology choices have to scale with the business.
While there are certain areas that can be future-proof, more often, they’re not viable long term. Scaling companies and software is an ongoing and natural process, rather than a manifestation of debt. Imagine trying to wear toddler-size shoes on your adult-size feet — it wouldn’t work, and it certainly wouldn’t provide an optimal experience.
It’s tempting to assume anything can be bulletproof, but the reality of life often proves different. We need to constantly be evaluating the suitability of what we’re building for the outcome we want to achieve.
Because technical debt is often used to justify an array of vastly different challenges, we’ve become desensitized to it. It’s a classic “boy who cried wolf” scenario — when we repeatedly misclassify minor obstacles as severe, we’re unable to address those that really are. As leadership expert Patrick M. Lencioni says — “If everything is important, then nothing is.”
It’s impossible to get company buy-in for unspecified work when the issues it addresses and its benefits are unknown.
Instead of categorizing obstacles as “technical debt that must be resolved immediately,” it’s necessary to dig deeper and provide context, especially to non-engineering departments. Armed with an analysis of a problem we’re facing, an explanation of its negative effects, and possible positive future outcomes, we have a better chance of that problem becoming prioritized and solved.
A framework I’ve used at Help Scout to tackle the shortages of our marketing site focuses on cross-functional impact:
What’s the problem we’re facing?
Our deploy pipeline is unreliable, resulting in occasionally not being able to publish changes.
How does it affect us?
Contributors cannot release their work; our SEO ranking falls; audience engagement and brand credibility decrease.
What are the benefits of addressing it?
Bolster user confidence and build reliability of releasing new work without a decrease in engagement metrics.
What is the proposed solution?
Implement a better pipeline with more thorough, resilient testing.
While the example is simplified, it portrays the amount of context necessary to understand the severity of an issue and determine whether it fits into organizational priorities. Depending on who you’re communicating with, their needs and goals and knowledge will be different. Our communication has to be fine-tuned. If we’re talking to a Product Lead, this level of detail might be enough. When justifying it to a CTO, we might have to provide more of a technology deep dive.
Effective teams are focused and intentional — they interpret and assess work based on the value it delivers internally and, even more importantly, to their customers. When we become proficient at succinctly communicating issues and solutions, we enable meaningful change.
The lifecycle of the Web
Anything we create will inevitably age and become outdated — most likely faster than we expect. Keeping in touch with modern technologies, design trends, and Web platform standards feels daunting, especially when managing customer expectations.
Technical debt becomes a convenient blanket statement entailing frustrations, rushed decision-making, lack of process or architecture, and tedious maintenance tasks — the get-out-of-jail-free card for delivering a subpar experience.
It’s crucial to understand that as software and design grows older, that doesn’t necessarily mean we’re dealing with debt. We must look deeper under the surface to find the root cause of bottlenecks we’re facing. Only when we carefully assess the symptoms can we find solutions to building products that last.