How do you manage technical debt that isn’t technical?
How do you explain to managers and MBAs how certain choices affect software in terms they can understand?
How do you keep track of shortcuts in features, functionality, and UX? And explain how they cost more to correct the longer they’re missing?
With a new twist on an old metaphor, that’s how.
Introducing the Feature Debt Metaphor
I introduced the concept of “feature debt” (aka “functional debt”) around the office sometime in 2013. It’s a sister term to “technical debt” that captures the shortcuts we take with product features instead of the code behind them.
We incur feature debt when the quick and dirty way chosen to shorten dev time has a component that users can experience. Debt signals an incomplete feature or functionality. It’ll probably annoy a user eventually, maybe enough they consider it a bug.
This new metaphor stopped regular arguments with product owners (POs) about prioritizing technical debt. Most of these were about why some of “that techie stuff” needed urgent fixes and others didn’t. And why we should not treat some product “gaps” as bugs. It was an effective metaphor for talking to the business about deliberate “holes” we left in the product and how their impact grows with time. Unlike technical debt, feature debt issues weren’t “some technical health thing” we did to keep our productivity. But instead, a place where the product owners took a shortcut the users can experience. A place where obvious features or functions should be but aren’t.
How can you tell the difference between feature debt and technical debt?
Users can directly experience feature debt. Not as a side effect of long-term reduced dev team productivity like technical debt, but as a behavior of the product.
Alternately, if the only people who will ever see the problem are the product devs, then it’s likely technical debt and not feature debt.
Got an example?
Of course. Let’s create a pretend vacation request form. Here’s a wireframe of the MVP (MVF technically):
We can select some dates and a “time off type”, then submit the form to save the request to the database. That’s it. That’s all we need in the MVP.
But we have a twist! This is actually a new UI on top of a legacy database. The old UI looks more like this:
It has several features our MVP does not. Here’s our short list to make this reasonable:
- Types restricted to only what the user has available
- Choose a different type for each day
- Specify how many hours to apply to each day
Now we’re looking at potential feature debt.
If our intent is to fully port this app, then those three things above become instant feature debt. That’s the side effect of needing them but not implementing them in the MVP.
If our intent is to only port as much of this app as needed to prevent “corrupt” data, then the list is shorter. In this case, only the item for restricting the time off types for the current user becomes feature debt.
As examples go, this one is rather small and simple. In practice, I’ve found the feature debt is often much more obscure workings of products. These are usually things only a small fraction of the users need or would encounter. Or corner cases that are more expensive to handle than to let blow up. We are making ROI decisions here after all.
Are all possible features part of the debt?
No. The key reason to go from the “nice to have” backlog (or ideation tool) to the “feature debt backlog” is the intent of the PO to have the feature. Just because you think of a thousand cool features you could add doesn’t make them feature debt. If it’s not a feature that you must add at some point to be complete, then it’s just another feature on the wish list. Intent matters.
Are performance issues feature debt?
I prefer to make them feature debt. While not all nonfunctional requirements will be feature debt, I prefer to keep the user-facing ones in that category. Anything you’d classify as a UX feature fits the metaphor in my book. End users experience problems with performance, security, usability, and many of the -ilities (even if they can’t articulate it). So I prefer to treat these as product features when I can convince the business of that. Once product features, making them feature debt is natural.
Are “messes” feature debt?
I see you read Uncle Bob too. Apply Fowler’s Technical Debt Quadrant to feature debt just as you would do with technical debt. Messes can be feature debt, but just as with technical debt it’s best to take out debt as a deliberate act. Don’t feel you must treat all quadrants the same either. It’s natural to treat them with different priorities, budgets, and feelings. Debt management is all about ROI. So think long-term and make profitable decisions. Some debt is best to carry a while.
Are missing support/ops features feature debt?
Most likely. I’d err on the side of making these feature debt, but this could depend on how you structure your support process. The typical large software house has dedicated support or hosting teams that field requests before the product devs get them. If those teams would use those missing features, even if it’s just to pull info to give to the dev team, then it’s feature debt. Those people are users too. Are you a smaller house without that support/ops buffer? Then I say treat yourself as a user because you are one. When you scale, those teams will become users anyway.
Why introduce a new term? Doesn’t “technical debt” cover this?
In short, “clarity” and “sorta”. Settle in for story time with me here.
In 2010, I joined a “new way” team redesigning and porting a massive commercial enterprise web app. Our IE-only product needed to work cross-browser and have modern UX, and our waterfall inspired approach needed agility. Plus we couldn’t alter the database, and the backend code wasn’t worth untangling to reuse. So naturally this project took a while to hit its stride. And many of the features we needed to port were too large for a release cycle. So we intentionally accumulated “gaps”.
After a year or so of team growth and churn, we began getting customer feedback about questionable “bugs”. A few of the original team realized these were some of our “intentional gaps”. This lead to lawyers arguing the semantics of “defect” and “enhancement”. If you’ve never worked with an enterprise-scale ISV, then you’ll just have to take my word here: this can become a massive revenue-carrying headache. Anyway, shortly before this we decided to ensure our technical debt was visible to the business. That is, we put it in our issue tracker instead of somewhere only devs would look. It only took a few fights over “defect or enhancement” before we agreed to record these “gaps” somewhere. The technical debt ledger seemed like an appropriate place since the metaphor fit. We assumed this would make it easier to prove our intent, and quicker to answer the “bug or gap” question.
Another year or so and all the backlog items labeled as technical debt started to lose recency and thus clarity. They became a big clump of all parts of Fowler’s quadrants. Few people could rank them by importance. Definitely not the POs. They saw all technical debt as “stuff devs complain about but rarely affects customers”. So they passed over it, becoming familiar only when desperate. I can’t blame them, I do the same to some of the less interesting requirements. This made it challenging to find if a reported “bug” was a true defect or an “intentional gap” hidden somewhere in the technical debt ledger.
This was also around the time the term “technical debt” began use by people who didn’t study the metaphor. I was on the edge of a debt spiral fueled by semantic diffusion and poor estimation. Some of our less experienced teams tried recording all their gaps as “technical debt” to “fix later” (read: when it catches fire). These gaps were mostly user-facing and often inadvertent. In their innocence, the devs thought the gaps were inconsequential. And with their naïve and muddled explanation, the business didn’t realize the devs were wrong at first. I was certain this would cause support cases and maybe lawsuits. What I needed an explanation of the problem that didn’t seem fussy or pedantic.
I coined the term “feature debt” as a counter to a “tech debt” claim in one of those “fix later” conversations. It clarified things, so I kept using it. The teams and POs gobbled it up. The rule of thumb about users experiencing the gap made it intuitive. And as new jargon, it gave me a chance to explain the metaphor.
“Feature debt” makes managing the product’s “debt” ledger/backlog easier for everyone. Our POs especially have an easier time judging how to pay down “debt” if end users can experience it. The term gave the POs their own metaphor to use without mixing it with things users can’t see or feel. More precisely, without mixing it with things they “just don’t [care to] grok” since they aren’t devs.
I feared this new focus on feature debt might take away the slice of the release allocated to technical debt, but it hasn’t. It actually increased the total slice for all debt. The POs want the feature debt slice for selfish reasons, so it takes care of itself. They also understand we need a technical debt slice too. So now they just trust us architects and dev leads to groom the technical debt ledger. Then we fight for a bigger slice when needed. This seems a better use of resources to them than the old way. That is, them glazing over as we attempt to explain the relative business importance of each technical debt item. They just saw that as squandering time since they usually deferred to us. The process is smoother now and all involved are happier as a result. In true lean fashion, we removed a bad process instead of optimizing it.
So there you have it. That’s feature debt. I’d love to know how it works for you. Please let me know in the comments below!
Featured Image: “No Chip Reader Yet Sign” (CC BY 2.0) by stevendepolo. Cropped by Jason MacDee.