Don’t be Afraid to Ditch Features from your Software

Sometimes Less is More

Grant Gadomski
Walk Before you Sprint
7 min readNov 7, 2021

--

I think one of the common mistakes we make when building great software (especially in an iterative environment) is putting too much weight on adding more features, and too little weight on refining and sometimes pruning existing features to create a better developer & user experience. In the development world our conversations tend to focus more on putting processes, tools, & structures in place to deliver more features faster, and less on collecting valuable feedback about features already delivered to adjust strategy accordingly. Instead many teams only think about already-released features when defects or enhancement requests pop up. But there are costs to keeping a feature around, and ignoring these costs (from an IT & user experience perspective) can lead to suboptimal UX & product outcomes. Teams should consider an additional tool in their product ownership belt when appropriate, the big red delete button, for the reasons below.

Better Development Outcomes

There’s an old saying in programming that great developers hope to delete more code than they write. While this is (usually) an exaggeration, there’s wisdom behind this thought process. Each line of code in a system comes with maintenance costs: It’s one more thing to learn when coming up to speed, one more thing to think about when touching coupled code, one more thing to verify during dependency updates, and one more thing that can break at 2am in production, causing the developer on-call to be quite grumpy the next day. Over time these thousands of lines of code add up & can calcify if not frequently addressed, leading to slower cycle times (as even seemingly unrelated changes take longer to develop) and higher change failure rates (as the challenge of fully testing the growing codebase grows).

At the same time updating or deleting existing code without affecting functionality (a.k.a. refactoring) can be challenging from both a technical & project management perspective. Refactoring is a process that most development teams agree they should do frequently, but many struggle to stomach the brainpower & time needed to truly redesign swaths of code towards higher quality without users noticing a thing. While better automated testing & DevOps practices come with direct resiliency & cycle time benefits that senior management can see value in, convincing your checkwriters that you should take time to redesign something that’s already finished & running in prod can be a very tough sell.

Instead flat-out removing a feature (and all the code that goes with it) can reduce system maintenance costs by a fair amount, especially since many of the less loved features in your system don’t get technically refined as often, and therefore their code tends to get stale & poorly maintained (and is therefore harder to upkeep & work with when building a new coupled feature). When refactoring, complex bug-fixing, or challenging coupling conversations come up concerning a feature that provides questionable (at best) value, it’s worth discussing whether this & future maintenance tasks are even worth the cost.

The Paradox of (User) Choice

“But what about user impact?” you may say, “Won’t our users get mad if we take away this feature?”. While some may, others may see benefits from you removing this feature.

The book “The Paradox of Choice” by Barry Schwartz discusses an interesting phenomenon where when we’re presented with too many choices at once, instead of this making us happier like we’d assume (more customization & agency is always better, right?) it actually makes us more stressed during the decision-making process and less happy with our ultimate choice than if we were presented with a more streamlined number of options. Think about the last time you bought jam at a grocery store. You find the jam isle, stroll up to the shelf confidently, and (if you’re like me) are quickly amazed by the sheer number of different brands & flavors available. So much so that you either reach straight for your tried-and-true (brushing past all the other options), or spend a full twenty minutes of your precious lifespan scanning jam packaging trying to find the perfect one for tomorrow’s bagel, before “settling” for one that seems good enough, but still feeling that pit in your jam-loving heart that another one could have been the better option.

While not all of a software’s features are laid out to the user as obvious tradeoff-style choices (like those jam jars), most pages in a typical piece of software are filled with data and various options that the user can pursue. Clicking an option takes the user to a different page (and down a different experience “path”), and it takes valuable time to either pursue this path fully or return to the previous page (this time representing the “cost” of each option). Therefore if you present too many options on the same page your user can start to feel like the hypothetical jam shopper above: either bee-lining to their typical option or perplexed & stressed in front of a shelf with 40 different varieties of delicious choices.

Google does an excellent job at avoiding this paradox of choice, even with their ever-expanding library of services. When you navigate to google.com the center of the page only contains the web search bar, their main service (and probably the reason you’re there). Clicking into the waffle menu in the top right presents their full list of services, but even this list is pruned regularly to make sure it doesn’t grow too overwhelming (remember when Google+ was on there?). By regularly pruning their feature list down to the ones that most users love, they ensure the users who know what they want can access it quickly (without wading through the clutter of less-used features), and the less pre-decided users aren’t faced with an overwhelming list of options.

Deleting Involves a Calculated Choice

Like so many other things in software, the decision to remove features often contains a cost-value analysis with a potential strategic element thrown in.

For a feature without strategic importance, your choice probably comes down to the question of whether the value your users get from it is worth the cost of maintaining it. On top of usage, sentiment, brand, & other factors, value calculations should consider the negative possibility of clutter & choice paralysis (described above) alongside possible knock-on benefits, like making the software seem more “full featured” and therefore worth the user’s time/money even if they don’t use all available features. Costs can be represented by both actual maintenance costs and the value the team could be generating by devoting said maintenance time to other development activities (the opportunity cost).

Now there could be a situation where a feature represents a new strategic branch or shift for this piece of software. Said feature may benefit from other planned features in the backlog, and therefore does not showcase potential peak value upon initial delivery. This strategy element adds another layer of complexity to your decision making, for now you have to consider the odds that the full suite of planned plus current interrelated features will provide value greater than their collective cost. When factoring in this strategic element, consider whether the current feature(s) are underperforming stand-alone expectations. Could this be due to an underestimation of their dependence on the full suite, or could it be a bellwether for a potentially underwhelming strategic direction?

Overcoming the Emotional Aspect

“Learning is best done through failure” is both one of the most useful pieces of advice, and one of the hardest to follow. Leadership gurus, self-help coaches, and entrepreneurs love talking about how they got to where they are by going through a plethora of professional (and sometimes personal) failures, but when the average person tries to apply this mindset we’re faced with the challenging truth: Failing sucks, and it will never not suck. The now-retiring CIO of the company I work for once explained that the reason we learn so much from failure is because of the pain it causes us. When we’re successful at something we tend to not learn much from it. Our brain goes “oh cool, that worked” and moves on to other things. Whereas when we fail at something our brain naturally obsesses over that event and its causes, creating a stronger imprint of “well that sucked, I’m not making those mistakes again”.

Calling time on a feature already in production can feel like admitting failure, and it hurts because it often carries a history of late nights, filled whiteboards, & seemingly impossible challenges, but also optimism, camaraderie, & the pride of creation. Removing a feature from production can make you feel like you’re dishonoring everything that went into getting the darn thing into production.

But sometimes features no longer provide the value they once did. The competitive market shifts, user needs change, new features overshadow older ones, or the product strategy evolves. When this happens there’s no dishonor to retiring a feature that once provided oodles of value, but that has faded with time.

Other times the feature just flat-out doesn’t provide the value you were hoping for, and it hasn’t from day one. Software development is and forever will be a long series of educated guesses, from ideation through design & development, into testing & delivery. Over time we’ve made better guesses through improved market research tools, Agile & iterative development, and better DevSecOps practices, but there will always be uncertainty in every stage of delivering a product or feature.

The key is to avoid the sunk cost fallacy, expressed by thoughts like: “We spent so much time and money getting this feature into production, we can’t just waste all of that by pulling this out!”. Unfortunately that money’s already been spent, and the only thing you’re doing by keeping the feature around is increasing your maintenance costs. Instead learn why this feature‘s bang doesn’t seem to be worth the buck, adapt your practices as-needed (but don’t just change things for the sake of changing things), and make a rational, strategic decision on whether you want to keep this feature around, make some changes to it, or nix it.

--

--