The Cost of a Feature

Posted by Monday, November 30th 2009

The other day, I talked to Paul, a product owner, about a feature and said I wanted to remove it. He said, “no, we might as well just leave and not use it, it’s there, it’s free, maybe we’ll use it at some point, and there’s anyway a cost associated with removing it.” I agreed with what he said at the time, but something about what he said kept nagging me. It felt like I was missing something. I think I’ve understood what it was now, something about the cost of a feature – obvious in hindsight, but it took me a while to get there. What I realised was that existing features are not free. Or, phrased differently, finished features lead to development cost even if you don’t touch them.

The feature we were discussing was ‘presearch’, which allows us to predefine destinations for specific user searches that we feel don’t lead to optimal results. So if somebody searches for “sony tv”, that could have a predefined search result that points it to the Televisions category and where the search engine is asked to provide results for “sony televisions”, for instance. These predefined search results sit in a database table which has a couple of thousand entries in it, more for some countries, less for others. The reason why I felt we should remove it is that it requires manual maintenance of the presearch results and that just doesn’t scale really well. The result is that we don’t actively maintain the presearch values, so we don’t really know if they improve searches or make them worse.

Disregarding the benefits of the presearch feature for the moment: if we just let those couple of thousand predefined search results sit there in the database and leave the code in, that doesn’t cost us anything, right? Wrong. Here’s how it cost us this last week:
- One of my colleagues spent a day or so trying to figure out why a particular search he was making was getting very strange results when others seemed to work as expected – the reason: that one search happened to hit a presearch keyword.
- When making a code change to the way we treat searches, the change became more complicated in order to ensure that we didn’t break presearch queries.
- To be sure we understood how the features should interact, we needed to communicate with some people at the US office, which due to time differences and a couple of emails going back and forth took us a couple of calendar days.

Now, we don’t always touch code that is associated with presearch (or some other feature X whose business value might be in decline), so in our development team we don’t get this level of cost every week. But it happens often enough to be significant. And what’s more, in QA terms there is a probably larger cost associated with regression testing every existing feature in a large system.

So, my picture of what a feature’s lifetime cost looks like has changed like this:

FeatureCosts

Basically, there is an up-front development cost which includes designing the feature (business/product owner-type work), implementing it (programmer-type work), verifying it (QA-type work) and launching it (CM/system operations type work). Once it is included in the product and live, it continuously incurs what I for want of a better word will call an ‘ongoing cost’, not just in operating or maintaining that feature, but in development of other features. By development, I mean product definition, implementation and verification, so ongoing costs are made up of these components:
- Slower decision-making/added communication due to the larger amount of things to know and think about, both when defining features and implementing them. In the same vein, increased likelihood of mistakes in feature specifications or implementations due to the complexity of feature interaction.
- Slower implementation of new features due to the additional complexity of the system. It is harder to figure out the right way to fit things together if there are many of them.
- Regression testing costs that increase with every added feature.

OK, so if that type of diagram shows the lifetime cost of a feature, it becomes pretty apparent that for a long-lived system, the initial development cost of a feature might well be much less than the ongoing cost that follows it. Here are some things that reduce the ongoing cost:
- Automated testing: doing this well has an immediate effect on the cost of regression testing. However, doing it also has an impact on the cost of adding or changing a feature, since it is likely to break the automated test. Quality test code is important here, the problem isn’t solved by just having automated tests in place.
- Implementation quality: investing a little bit more at the development stage to ensure that the implementation is good can lead to significantly reduced maintenance costs. Insufficient investment in implementation quality is a part of what is known as technical debt. Having the right implementation means that it is easier to understand it, test it and change it without breaking it. It also reduces the interaction between features, which reduces the ongoing costs directly.
- Documentation: having described what the feature does and how it is supposed to interact with other parts of the system makes it easier for people to understand it when they need to add or update a related feature later. Of course, creating and above all maintaining good documentation is not free.

I used to think that old software systems gained cruft and lost flexibility over time only because of poorly implemented changes that would accumulate over time. That would mean that good engineering practices – being good at the three bullet points above – should be a sufficient solution to prevent system ageing. I now think that the simple facts that systems gain more features over time is enough, even if every feature is perfectly implemented, to create a significant slowdown. So that means that to keep a system healthy and modifiable/agile, you need to decommission features over its lifetime. It would be great to be able to somehow measure the ongoing costs and benefits of features so you could decommission the ones that have too high ongoing costs relative to their benefits.

Comments (3)

Comments (3)

Comment RSS  |  Trackback URI

by oskar in December 1st, 2009 at 1:39 am    

Hello there!

Well said, I heard you began writing here from your brother btw. ^^

I have come to associate this problem with a combination of two concepts which I think of as Metcalfe’s Law and Erlang. I am sure neither is mathematically relevant to the problem in question, but the concepts interact. Note that I am knowingly corrupting these scientific concepts for very unscientific reasons, I’m not an authority in the field and don’t want to pretend to be one either.

The Erlang says: A feature which is not 100% flawless is less than 1 Erlang. We can assume the defects behave as noise in a phone line to make this connection. For example: 0.9 Erlang means 90% flawless and 10% defect.

Metcalfe’s Law says: The number of links increase exponentially with each connected node.

Combined these two then say: The noise level within a system increase exponentially with the number of features, unless you have a quality level which disqualifies features with less than 1 Erlang.

To understand what I mean with this you might need to follow my logic about noise. Noise adds to itself as roughly the square root of the number of sources. This means that the noise level raises very very slowly if your quality level is at about 0.9 Erlang. The second insidious part about noise is that we humans have noise-reduction hardware in the brain which is always active and filters noise from reaching our consciousness. This hardware is in practice a threshold which as long as the noise level is low enough removes our ability to detect it with our senses or emotional systems.

The practical application from this reasoning is that you can use this to your advantage when beginning a new project. If the thing you are building is small and uncomplicated you will be able to get away with a reasonably low quality level since the noise will be fitted beneath the threshold of humans and go undetected. This won’t make the most astoundingly high quality product, but it is quite likely to work to some degree.

However, when you aim at something which is intended to grow over time, which might be the more common scenario these days, you will need to set rigorous quality standards and make sure everything gets all the way to 1.0 Erlang before any new nodes are added to the system. If you fail at this and instead proceed with developing the product at 0.99 Erlang on average you will eventually run into an immovable object of background noise.

(Some might argue here that the system can be split into cells which break down the exponential increase from the number of nodes. This argument forgets that the human brain which uses the system is a master node which connect all nodes with each other beneath its semiotic parent (brand/product/market position…).

Since the noise level was built by adding tiny amounts with every component there is no reasonably single-fix that removes the noise from the system. I believe this is a rather common pattern of ageing for software products.

This is not a purely technical matter either and goes with dealing with market risks as well. In this case it is a lot trickier to find any standards to follow for how we measure 1 Erlang of product value. (I am leaning towards a solution where you focus your attention at the links in the system for this one.)

Its really hard to make this type of comment “short and snappy” btw. :-)

I wrote something similar to this a few months ago over here: http://gamesartdesign.blogspot.com/2009/10/failure-of-repeated-success.html

Maybe its time for one which is more directly on topic. ^^

by petter in December 15th, 2009 at 11:27 am    

I think you’re talking about how how imperfections multiply and cause more friction than the sum of each individual contribution. That is probably true, and I think that in most systems, solutions that are less than perfect is the main reason why making modifications is slower and more expensive than you’d desire. The point of my post was that even if all solutions are perfect, a system with more features is going to become harder and harder to modify over time unless you retire some of them. I think the first priority is making ‘good enough’ (never perfect, of course) solutions, and the second is retiring features whose value has diminished. Or rewrite the whole damn thing and start over. :)

by Luc in December 18th, 2009 at 2:44 am    

I totally agree with this article, and I think this can also apply to business processes. The cost of “ongoing maintenance” of something useless (or not very useful) is often greater than what most people will admit to. There’s always that little something that causes you to take your eyes off the important thing.

I call that the cost of distractions.

Related Posts (5)

Leave a Comment