Warakorn - Fotolia
"Technical debt" sounds scary. Most of us rightfully want to avoid owing more than we have, after all, and it's hard to repay technology with technology since there's no objective measure that makes any sense1.
Technical debt doesn't have to be scary, though. Much like current scientific research owes much to the science of the past, programmers can use the worthwhile efforts of others to save themselves from reimplementing complex features.
At the same time, though, when you use work done by others, you do incur a debt -- you have to use their libraries or work in the way that they intended, and that may not work with your plans.
What is technical debt, really?
Wikipedia says that technical debt is "a concept in programming that reflects the extra development work that arises when code that is easy to implement in the short run is used instead of applying the best overall solution." That's a good definition, but it's a bit narrow.
Ward Cunningham, inventor of the Wiki, describes technical debt slightly differently; he says that if you fail to align your program's design with what you understand to be the proper way of thinking about it, you're going to stumble over that poor alignment, and that will negatively affect your design and your application.
That, too, is a good definition, and it's the one that most other definitions use as a solid base. However, he's trying to describe a negative effect, and I think technical debt goes beyond that.
To me, technical debt is a reflection of what you rely upon when you write programs, with both positive and negative effects. Technical debt reflects the cost of the choices you make, choices that are often made without regret.
An example of technical debt with no technical stuff
Indulge me, if you will, by reading the lyrics of a short song; if you'd like, you can skip to the next section of the article and not miss too much, but I think it's worthwhile to read anyway.
Come and listen to my story about a man named Joe,
All he really wanted was to make his project go.
He found himself a repo and it looked like it was cool,
So he added a dependency and made himself a fool.
A fool in technical debt, that is.
Believe it or not, these lyrics represent a sort of technical debt. (It's actually a cultural debt rather than a technical debt, but the analogy is strong. Bear with me, Padawan.) In writing it, I'm making an assumption that my readers are familiar with the theme song from The Beverly Hillbillies, an American television show that ran from 1962 to 1971, and that still runs in syndication today.
If you're not familiar with the theme song, reciting the lyrics might sound odd; the beat placement becomes variable. International readers, especially, might struggle with the meter.
It also breaks with the theme of the article in which it's placed2. Readers of this article are looking for technical content, and here we have song lyrics, though they refer to things like repositories and projects. (We're even discussing music, which hardly fits in with the theme of TheServerSide.com.)
As an author, I'm asking my readers to bear with my indulgence. Readers don't have to keep reading; there's enough good content on the internet that there is plenty of opportunity to go elsewhere for stuff that's more interesting. However, I'd offer that it represents a sort of cultural debt as an analogy for technical debt very well.
I expended effort to write a short song to illustrate a point, and I chose to do so even though it might confuse some readers3. That's debt.
Choices in technical debt
As I said, to me, technical debt is reflected in every implementation choice you make; from operating system, to programming language, to libraries, to data storage choices.
Many choose Java as their programming language, for example, because the Java virtual machine (JVM) prevents them from relying on a particular operating system, but that implies a debt on Java itself4.
Likewise, most of us are comfortable using relational databases (or even reasonable facsimiles thereof, like MySQL), application servers like WildFly or Tomcat, and microframeworks like DropWizard. There's also a big push towards containers and moving entire applications into virtual machines on the cloud as a core architectural design (as opposed to handling excessive load.) Our applications rely on these products working properly; they each represent a crucial point of failure for every program we write.
The level of debt we owe to these products is reflected by two things:
- The reliance on a product fulfilling part of our architectural requirements.
- The direct ties to the product.
To explain, imagine that we have an application that uses MySQL. There are two axes of dependence here; one is that we use a database and the other is that we use MySQL itself.
It's possible that we can replace MySQL with PostgreSQL should MySQL fail as a whole -- that's our dependence on the architectural role of MySQL.
It's also possible that a lot of SQL was written specifically for MySQL and, therefore, migrating away from MySQL will require a good bit of effort.
Here, MySQL represents debt reflective of how closely we've tied ourselves to it. The same statement goes for any and every dependency for our code, whether it's as simple as SLF4J or Guava or as complex as GigaSpaces XAP.
What do you do about technical debt?
In the end, you pay debt where you're willing to pay it. The definition of technical debt as offered by Ward Cunningham is negative, and that's a decent way of thinking about it.
When you make a choice to do something or use something, you should be asking yourself if this is an investment in time and effort that is worth it and what this investment will cost you over the life of your project.
Is the investment worth the time? Does it actually provide long-term value to your project? Will it change your coding conventions such that using the product will stick out like a sore thumb unless you create some sort of integrated facade?
All of these (and more) are worthwhile questions. Don't be afraid to ask them -- and don't be afraid to reject a solution because of the long-term technical debt that it might incur.
- With money, it's easy; if you borrow an ounce of gold, you are expected to repay that with roughly the value of an ounce of gold. In programming, though, you don't have a good measure; one block of ten lines of code is not going to be worth the same as another block of ten lines of code.
- Holy fourth wall, Batman! I think it's been broken! (To which Adam West responds, "There is no fourth wall, Robin. It's only a camera.")
- My readers might be grateful to know that my original thought was to use the pattern of The Rime of the Ancient Mariner by Samuel Taylor Coleridge. Technical and cultural debt, indeed. In the end, I chose not to mirror the Rime because it would have been a lot of effort for relatively little reward, and it would have been distracting to keep hearing Iron Maiden in my head as I wrote -- and the reason this gets mentioned in the footnotes at all is because it's a good example of trying to choose your dependencies wisely.
- Oracle's behavior as a steward of Java is very important here because we rely on the JVM -- and, implicitly, rely on Oracle's willingness to continue to provide the JVM -- for better or for worse. Yes, there are alternative JVMs like OpenJDK (linked to Red Hat since they have an OpenJDK build for Windows) and Zulu (from Azul Systems), but my experience has been that the Oracle JVM remains supreme, and the Java ecosystem relies upon Oracle as a fundamental supporter and provider.
What is technical debt and why should CIOs care?
Breaking the software development bank balance with technical debt.
Reduce technical debt and make code maintainable.