About a month ago, I re-posted something that I had written about tech debt for the Infragistics blog. This turned out to be a popular post and it generated some reader questions. Today, I answer one of those questions, which basically amounts to “wherefore art thou, tech debt?”
What Generates Tech Debt?
No doubt, you’ve heard the Shakespeare-as-Juliet ask, “Romeo, Romeo, wherefore art thou, Romeo?” Most people imagine Juliet standing on the balcony and offering a maudlin request blindly into the night — “where are you, dude?” Interesting bit of trivia: Juliet is not asking where Romeo is, but why he is. She poses a much more interesting question. “Why do you exist?”
Accordingly, this post concerns the wherefore of tech debt. Why do we find ourselves saddled with this stuff?
Ignorance Is Bliss
I would contend that most tech debt originates without much awareness on the part of the borrower. In fact, I think that the overwhelming majority of it occurs this way. It’s as though they’re driving through a city that issues automated speeding and red-light tickets, racking up one after another. There’s no awareness of the incurred debt until it arrives in the mail one day, all in a big lump sum, to deliver a gut shot.
So it goes in most shops that I encounter with significant technical debt in the codebase. They’re aware of the negative ramifications of the technical debt—feature slowdown, quality issues, requests that the architecture won’t support, etc. Awareness of these issues is usually what brings me in the first place. However, they don’t associate that state of affairs with any specific decisions that they make in the codebase.
To get more concrete about this, consider a shop that earnestly doesn’t perceive a drawback to copy and paste programming. For the sorts of people that read this site, I imagine that seems inconceivable. But, believe it. Plenty of shops out there don’t think twice about such practices and then reap what they unwittingly sow.
By and large, this occurs in places with heavy “duct tape programmer” cultures. Often, an organically and gradually developed software competency leads to this situation. A single, self-taught individual starts writing some VBA code and over the years, that gradually turns into both an impressive accomplishment and a mess.
Whatever the backstory, though, the result looks similar. The shop in question struggles, vaguely understanding that it did something wrong at some point but without grasping more detail. This situation can typically be corrected with some leadership by example.
We Must Get This to Market!
This one occurs almost as commonly as the "ignorance is bliss" situation. Here we have a department that believes it needs to go too quickly to worry about code quality.
You might think that only startups behave this way, but this is far from the truth. You can find this in companies of every shape and size. In my experience, "we don’t have time to worry about code quality because of our unique situation” takes third place as the most common excuse. First is, "we have a really steep learning curve because our domain is uniquely complex." The close second is, "we can’t unit test because of our specific situation." But after those two, "we’re in a time crunch" inevitably follows.
To me, this presupposes something widely assumed but (to my knowledge) never proved. This mentality treats quality and time to market as opposite ends of a dial, like hot and cold in the shower. “We need to hurry, so make it bad.”
Of course, the don’t actually say that, but the underlying tradeoff informs management decisions. From there, the culture assumes a decidedly “good is for later” vibe, making people feel guilty for things like spending time on design or refactoring code.
Frankly, I object to the premise. I don’t mean the idea that sometimes hurrying to market must happen, even if quality dips. That’s fine. I object to the premise that embracing sloppiness automatically translates to speed. All too often, it just translates to calling something done before it is.
But whatever the rationale, and whether beneficial or not, this approach piles up prodigious tech debt.
Tactical Tech Debt—A Rare Breed
When invoked, the tech debt metaphor invites parallels to financial debt. With financial debt, however, borrowers receive funds with fairly clear and understood terms. This allows planning which, in turn, allows strategy. Financial borrowers can easily have good debt.
In the software world, the equivalent would be something like the following: “if we hard code this setting, we’ll be able to cut the release a week earlier. We will need to fix this later, at a cost of 40 extra man hours, but we can better afford those in a month than we can now.”
Every now and then, something like this happens—but very rarely.
Sloppy Masquerading as Tactical
The second type, accrued under the general attitude of “we must get to market,” usually occurs when people think they’re taking a tactical approach. But what they do instead is offer a blank check, so to speak.
They don’t walk into the metaphorical bank and negotiate a loan with clear terms. They don’t knowingly pay an obvious amount of interest for the sake of enough liquidity for a time-sensitive investment. What they do is more akin to randomly selling their possessions to pawn shops and borrowing money from friends. They wind up with the money to make their investment, but without any inventory of what it cost them or means to assess whether it was a good idea.
Wherefore, Tech Debt?
We’ve looked at three different kinds of tech debt. One, the least common, involves rational, tactical thinking. The other two involve a lack of awareness of the cost of decisions being made. Whether the lack of awareness stems from obliviousness to the cost of owning code or lack of concern with it, indeterminate (and often substantial) spikes in the cost of ownership result. The code winds up with technical debt.
If we set aside deliberately-incurred tech debt (which represents a small contribution anyway), the why becomes easy enough to generalize. Tech debt occurs when “later” isn’t a concern. The oblivious shops flail just to keep their heads above water. The sloppy shops convince themselves that nothing matters beyond the now. In either case, later doesn’t matter.
The idea that tech debt arises from “later doesn’t matter” probably doesn’t strike you as profound. However, I think that something profound underpins this realization, particularly when we consider the ubiquity of tech debt. Most of our industry charges along to “later doesn’t matter” because we expect software projects to fail.
Wherefore, tech debt? Tech debt arises from the view that software living to fight another day constitutes victory. It occurs when you assume that you’ve had a good run, but it’s going to come to an end.
I would thus argue that tech debt finds its true source in our attitude toward software: disposable and inevitably rewritten. Tech debt is a self-fulfilling prophecy. We believe that software, in the long run, will fail to be maintained. So we fail to make it maintainable.