Whether you’re talking money or code, “debt” tends to be a dirty word. That’s for good reason—just as unchecked spending can lead to all manner of financial woes, poor software development practices can produce a bloated codebase that seems held together by band-aids.
But what do we really mean when we talk about technical debt? A while back, New Relic Developer Advocate Tori Wieldt shared this definition from developer Nina Zakharenko’s PyCon 2015 session, and it holds up well: “It’s the result of a series of bad decisions that force a developer to use more resources to accomplish less.” Here’s another good definition from Dan Radigan, senior agile evangelist at Atlassian: “Technical debt is the difference between what was promised and what was actually delivered.”
You can certainly find many other definitions and discussions of what constitutes technical debt, but they tend to come to a common conclusion: technical debt is an unfortunate reality for most software shops.
Technical debt has many causes, from sloppy development and organizational apathy to more productive reasons such as supporting urgent changes. As Tori wrote in her post: “In many organizations, the pressure to ‘just ship it’ is immense.”
So how do you contend with that pressure and the myriad other factors that lead to technical debt? According to the experts, there are two sides of dealing with technical debt: paying it back and preventing it from occurring in the first place. In both cases, success depends on a mix of culture and process not just among developers, but the entire organization.
Managing and repaying technical debt
When properly leveraged, technical debt can sometimes be a critical tool for keeping technical realities and business objectives in relative harmony. Most people wouldn’t be able to buy a house or a car without a loan, but the folks who do it right have a plan to pay back their debt. The same principle bears true in software: If you’re too precious about your code, you’ll never commit a line of it. Taking on a reasonable amount of technical debt—and having a plan to pay it back in the future—can be vital to the success of the overall product and organization.
“There will be times when technical debt should be endured for the good of the business,” says Todd Stephan, VP of software engineering at Ask Applications. “We have often seen ivory tower teams produce beautifully architected and designed software—months after the market window closed or first-mover advantage is lost.”
Even in an organization that places immense value on software quality, “technical debt is still sometimes an unavoidable reality,” according to Gady Pitaru, CTO of Badger Maps, a New Relic customer. It’s all about properly managing and eventually repaying that debt. Here are several expert tips for doing that:
1. Don’t sweep technical debt under the rug
Pretending that a stack of bills on your desk isn’t there doesn’t mean you don’t owe the money. The worst approach to technical debt is to bury your head in the proverbial sand.
“Technical debt shouldn’t be ignored, treated as taboo, or looked down on as problems with the engineer to blame,” Gady says. Instead, he advises, embrace technical debt as an opportunity to improve the system as a whole. “The best approach is to make sure [issues] are identified and tracked, so they can’t hide.”
Developer Stuart Gilbert offers (via Medium) three ways to reduce technical debt. The first is a straightforward method of being proactive about identifying new debt in your code as it’s created: highlight it. Stuart notes there are several ways of doing so; he wrote Papercut as a way for Java and Android devs, in particular, to annotate problematic code. It includes a tripwire designed to fail your build if the issue isn’t resolved, keeping it out of production.
2. Implement processes and methodologies that help, Part 1
Gady and Todd agree that the right processes and dev methodologies are critical to managing and reducing accrued technical debt. (We’ll look at how processes and frameworks can help avoid technical debt below.)
Todd says the right mix of development processes or frameworks “should include the ability to make choices about your technical debt rather than having it happen by accident or, worse, not even knowing that it is accumulating.” He notes that several such processes or frameworks (think Scrum or Kanban) tend to include some variation of the following:
- Transparency to the business on what they are buying for each release in “cash” versus what they are putting on the technical debt “credit card.”
- The concept of continuous improvement so that there is a formal way to improve the state of things if technical debt is not being managed well.
- The concept of a “Definition of Done” that teams use to define what a potential release candidate must include and must not include, with agreement from all involved.
- A process or framework that forces re-factoring. The canonical example is Scrum (and many other Agile frameworks), which embrace the fact that we don’t know everything up front, that we will sometimes be wrong, and that we will need to course correct.
- Giving technical teams a seat at the table when prioritizing work. This helps any technical debt that accumulates to be prioritized by the technical team as part of coming releases.
Processes, frameworks, methodologies—they all help you face technical debt. A common theme in technical debt-related advice is to not move new debt into some bug-tracking graveyard that no one has any incentive to work on or even monitor. Rather, treat technical debt like new features or changes.
“Whenever one of our engineers finds they have to make a compromise in quality and intentionally create technical debt—skipping writing a test to finish a user story on time, for example—it is tracked for the sprint in Trello,” says Gady. “Periodically, usually after a few sprints, all of the technical debts are prioritized by the engineering team and the most important ones are converted to user stories and go directly into the product backlog. We always try to add at least one or two technical debts to every sprint as part of our belief in having well-rounded sprints.”
If that sounds like work, it is. But dealing with technical debt can really pay off. Zoosk’s Lead Software Engineer Aideen NasiriShargh shared at New Relic’s FutureStack16 conference how his company slashed 20,000 lines of code—20% of the dating site’s codebase—that had been added by other devs during “experiments” or A/B testing. Doing so cut Zoosk’s page load time by 15% and boosted page views by 10%, he said, a big deal when romance is at stake.
You can watch Aideen’s entire presentation here: Zoosk Proves You Can Hurry Love After All. (Pay extra attention near the end when he shares key takeaways for engineers on how to sell the investment needed to create high-quality code. Our favorite? “Performance as a feature,” or treating application performance like any other feature you’re building.)
Preventing technical debt
Sometimes, of course, the best cure is an ounce of prevention. It’s not always easy, but often advantageous, to avoid creating technical debt in the first place. Here are a few tips:
3. Create a culture of quality
Teams that are built around a culture of high-quality software are simply more likely to care about preventing technical debt from creeping in. (And when it does occur, they’re more likely to be serious about paying it back later.)
“Preventing technical debt is a side effect of having a culture that believes in quality,” says Gady. “When everyone cares about creating quality software, technical debt is [more] easily prevented.” This culture has to run throughout the org chart, from the most junior developer to the engineering manager and above. It should permeate hiring, workflows and processes, performance incentives, and more.
When that culture is fostered over time, Gady notes, then “anything but quality software eventually becomes unacceptable, and technical debt is prevented as a result.”
4. Educate non-technical stakeholders on the realities of technical debt
Any dev knows that the aforementioned “ship it now” pressure within an organization can be very real—and that’s often when patchwork solutions get put on the codebase credit card. Todd says that having open, honest conversations about technical debt with non-technical stakeholders is crucial, adding that—just like individuals making household financial choices—different organizations will tolerate different debt loads or levels of risk.
Regardless of your company’s outlook, educate your stakeholders about what technical debt is and why they need to pay attention to it. And do so in terms they’ll understand: “Communicate the business impact of technical debt in business terms specific to your particular business,” Todd advises.
There’s a common language most businesses understand: money. Translate the costs of technical debt into bottom-line terms. You can even do a cost-benefit analysis of technical debt.
5. Implement processes and methodologies that help, Part 2
Gady shares several examples of processes and practices that can help build a culture of quality and prevent technical debt from accruing. These include requiring accurate, automated tests with each change in code, creating and following a set of code standards, doing code reviews and pair programming, and following a clearly defined QA process.
“We’re constantly working to include these practices into our scrum processes and daily cadence,” he says. “It takes perseverance, creativity, and a kaizen mindset, but in our experience the benefits have always outweighed the perceived downsides or overhead.”
Remember, you can do it! Dealing with technical debt may not be fun for software developers, but it’s an important part of the job. If you can communicate the importance of managing debt while finding ways to bake code cleanup into your processes, you might be surprised how much you can lighten the load.