Wherefore Art Thou, Tech Debt?
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 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 does not ask 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 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. But 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 blog, 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 far from it. 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.” “We can’t unit test because of our specific situation” follows closely in second. 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. The 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 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. But 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.
nice post. I think it can go well with the Beginner expert syndrome.
once you have this ‘expert’ guy that can block all the new ideas to do things better (you wrote about. you used the bowling techniques example).
https://twitter.com/ExpertBeginner1
Is it the organization that’s failing or the individuals? Do we blame the players or the head coach? At what level in the org chart do we say that it’s ok to not understand the state of the code base? I think that too many executives think that the software is the asset, rather than the code base. Nice post Erik. If we agree that market forces and the almighty dollar determine outcomes, then I think what you’re saying here is that tech debt piles up because orgs aren’t interested (financially) in keeping it at bay. And you are trying… Read more »
I think probably what I see most commonly is that organizations fail to understand the nature of their code. They consider it an asset (where I might even argue that source code is actually a liability, if not more on par with inventory), but when it ships, they also tend to consider it a solved problem, only to be revisited if you need to add something. And then, when you need to add something, it’s a whole separate thing. I think businesses tend to regard software according to a lot of bad metaphors (like widget assembly or building construction). This… Read more »
It’s not necessarily an expectation of failure. It’s sometimes that, if we are working on a special purpose application as opposed to a general purpose platform, we know that the requirements/market will eventually change enough that the vision which guided the application will cease to be relevant. If you need to make a fundamental change to the architectural vision of the software, it makes sense to just shelve the existing software and start from scratch, because really you are making a new application. Code can be more or less flexible, but it is not infinitely malleable. Of course, sometimes your… Read more »
This doesn’t sound particularly discordant to me with anything that I was thinking when I wrote the post,. I’m wondering if I should have picked a less pejorative word than “fail.” I didn’t mean “fail” in the sense of catastrophic results or incompetence, but in terms of the software failing to continue being fit for purpose. Perhaps I could have said that we expect software projects to cease to be or to become irrelevant. Using that terminology, I think it covers the idea that (1) an assumption you baked heavily into your application becomes untrue or (2) there’s no vision… Read more »
Indeed, I think we are in agreement. It is interesting that this expectation of non-viability is so pervasive. A coworker of mine mentioned the concept of MTR – Mean Time to Re-org. This represented the time between major changes in leadership/organizational structure/vision, and that each such shift represented a distinct possibility that the software project could be given a new direction (or just killed off) and that if you wanted to get anything done you had to ship your release within the window between re-orgs. In fact, his thesis was that the primary purpose of “agile” development was to facilitate… Read more »
Many developers write sloppy code fast. They’re rewarded for their accomplishment with new projects rather then maintenance, hence they never experience the consequences of the technical debt they create.
From a management perspective, once they’ve given an individual awards and promotions for their sloppy development, how do they make a u-turn and realize that what they rewarded is now crippling them? Whatever work that person did *must* be good because they’re our star developer. They’ll accept his appraisal that a new feature is difficult or impossible without questioning whether that’s because his own code is unmaintainable.
Looks like he took it down from his site, but Michael O Church once wrote a post that you might like, called the Shodan Programmer. Here’s a copy of it that was cached at something called “the old reader.”
https://theoldreader.com/profile/50e2e989bd9279050b0058ab?page=4
He basically calls the archetype you describe a “brawler” and describes how they advance in organizations.
There is also the “Tactical back stabbing variant”. On one of the projects I protested against the shortcuts we were forced to take, stating that it would compromise the quality of our code. Doing things “the right way” initially takes more time than just coding around. The back stabbing lie I was told, was that we would fix it later. Obviously, everyone there just knew that that would never happen. And indeed, it didn´t And yet another variant of deliberately incurred debt is when an application is only meant to be used for a short period of time. A couple… Read more »