Opportunity Cost for developers — or how I stopped worrying about the future and learned to code for the present

In this post I will discuss the importance of opportunity cost in development and how developers fall into the trap of developing for a future that will likely never exist.

Opportunity cost is a concept familiar to economists but, perhaps, not very familiar to most people outside the economics profession. The canonical definition is as follows, from Wikipedia:

In microeconomic theory, the opportunity cost, also known as alternative cost, is the value (not a benefit) of a choice, relative to an alternative. When an option is chosen from two mutually exclusive alternatives, the opportunity cost is the “cost” incurred by not enjoying the benefit associated with the alternative choice.[1]

A very simple example of what this actually means in real life is having to choose between two desserts, costing the same, in a restaurant. The opportunity cost of choosing the sticky toffee pudding is the loss of enjoyment from not eating, say the Eton mess. So, if you think you are going to enjoy the Eton mess more, then that is what you should go for, obvious stuff.

At this point you might be wondering how this relates to development, so I will provide a more relevant example.

Opportunity cost in development

The company was asked to create an online form that ensured that all necessary information was collected. The form required some complex validation rules, e.g. the employee/contractor had to provide home addresses and employment references that covered a period of three years. There were some requirements that were related to the company’s onboarding process, as it made sense to collect all the necessary onboarding information at this point in time. The form would be filled in by the employee/contractor from the comfort of their home with a paper fallback for the less IT savvy personnel.

The development team discussed the requirements with the sales team and it was agreed that this type of customisable forms with complex validation would be a good feature to add to the system so it was decided that it would be added as a generic feature rather than as a single form for a single customer. It is worth pointing out that this would be the third form type (arguably it was an enhancement of an existing form type) that was being added to the system.

The feature took a single developer (the lead developer in the company) just over eight weeks of development to complete, this did not include testing or actually creating the form itself, a rather time-consuming effort as it required several review cycles due to typos on both sides. The developer was suitability proud of his achievement, so much so that this feature would feature in quite a lot of conversations in the future.

Opportunity cost in time and development

· 1 week for custom form with validation

· 8 weeks for generic reusable form

The opportunity cost of this feature is all the other features, bug fixes, etc, that the lead developer could’ve worked on in those seven weeks, this is regardless of whether the feature was used or not. Note, it’s seven and not eight as that’s difference with the alternative, namely the week it would’ve taken to do the single form, although arguably given the actual usage, more on this later, it could be argued that the opportunity cost was eight weeks. To be sure this makes the assumption that the requirement had to be delivered, but that’s a conversation for another post.

The interesting bit is that the form the customer wanted was delivered and by the time I left the company there were a grand total of nine completed forms in the production system, all of them were completed during acceptance testing, in other words the form was never used for a real employee/contractor but, how about the feature itself? After all the advantage of adding it as a feature was that it could have been used by other customers, right? Well, it was not. In the, roughly, year and half between the feature having been released and me leaving the company, not a single customer used the feature. I feel that this bears repeating: Not a single customer used the feature. You could ask whether it was sold at all, how was it sold, how was it marketed. There was never a requirement to use it by any customer new or existing.

A quote from The Phoenix Project feels appropriate here:

Features are always a gamble, if you are lucky 10% will get the desired benefits, so the faster you can get those features to market and test them, the better off you will be.

May the future be with you

The main issue with the example above was that a single case was prematurely generalised to tackle all, well, let’s face it, some use cases that other customers may, in the future, have. A harsh but accurate description of the whole process would be that we tried to forecast the future and failed miserably, which is something that happens with depressing regularity as predicting the future is a notorious difficult business.

Unfortunately, confirmation bias and the availability heuristic work against us in these types of situations as we’re only ever likely to remember all those times when our efforts toward generalisation or extra features paid off. We have all undoubtedly thought something along the lines of :

Well, I couldn’t have predicted that

when talking about the shortcomings of a feature we have lovingly developed and yet we have undoubtedly thought how clever we have been to have added this or that generalisation or code for an extra use case that allows the new requirement to be satisfied with very little or indeed no development at all.

The point I’m trying to make is that by trying to tackle future use cases or generalising our code too early, we are ignoring the opportunity costs that this has and these costs can be massive. Furthermore, tackling the use case when there is an actual need, will likely result in a better feature as there will be a real need rather than an attempt to future proof the code, which unfortunately tends to be against the wrong future.

This doesn’t only applies to full features, this can happen when we try to generalise or future proof a small part of the codebase, after all an extra half a day here and there and suddenly you are talking about weeks of person days that have been effectively wasted.

Complexity and maintenance

In certain companies the urge to future proof comes from a difficulty to obtain a budget for development but perhaps paradoxically this approach to try to future proof everything makes it even harder to get said budget. The reason being that some (a lot?) of that budget is wasted on features/use cases that nobody ends up needing, with the consequent waste in resources and the negative feedback loop that this creates.

New approach

It is possible that doing an MVP feature and then refactoring to provide all the desired functionality could lead to higher costs. In the previous example, an MVP approach could not have been turned into a Full Feature but this is could be OK.

The question as to which approach makes more sense, i.e Full Feature vs MVP and refactor when needed, depends on how accurate The Phoenix Project quote is. If 10% is truly the rate for successful features in your organisation, the MVP approach is undoubtedly the right approach as on average, you will only incur a penalty one in every ten features.

It is a waste of time to write code and then do a feature that would negate the need to write the original code in the first place, but the whole point of this article is that this is no different and in fact, less likely, than the alternative, which is to write code that isn’t used.

Doing what’s needed

Next time you find yourself developing code to cover a use case that is not relevant now or you are generalising some code to better be able to handle the future, think about what else could you be doing of value, i.e. the opportunity cost, and you will, hopefully, restrain yourself. Remember YAGNI, you aren’t going to need it or are you?

Capgemini Microsoft Blog

Thought Leadership, Best Practices and Tips from Capgemini’s Microsoft Team

Capgemini Microsoft Blog

A place for Capgemini’s Microsoft team to share their experiences delivering cutting edge solutions for our clients using the latest Microsoft products. Follow us to keep up to date on trends, best practices, tips, revision guides and life in Capgemini’s Microsoft team.

Agoney Garcia-Deniz

Written by

Capgemini Microsoft Blog

A place for Capgemini’s Microsoft team to share their experiences delivering cutting edge solutions for our clients using the latest Microsoft products. Follow us to keep up to date on trends, best practices, tips, revision guides and life in Capgemini’s Microsoft team.