The Joys and Sorrows of Turbidostat-Based Development

Significance of features

Feature is a pure good. Feature creates wealth by solving business issue, directly or indirectly.

“Doing one thing and doing it properly” is not an argument against features, it’s just a call for the proper organization of code, for obeying single-responsibility principle. When you think about the whole of all software needed to run, let’s say, a gas station, you can’t say that it’s better that the gas station software cannot work with multiple currencies because of “doing one thing properly”. Software should help there. If it doesn’t, we, as software engineers, failed.

What blocks functionality from existence?

Given that features are so awesome, it’s surprising that we see them so little in the wild. Software seems to get simpler and simpler, it’s usefulness is driven by connectivity nowadays much more that by making more, better decisions.

What is in play here?

  • There is this “Testing/DevOps drive” that makes marginal utility of a new feature go to negative as the risk of adding new feature breaking current functionality outweighs benefits of that feature.

  • There is also “UX/Sales drive” that makes marginal utility of a new feature go to negative as the user’s inability to handle/appreciate it makes it not used, while lowering discoverability and hence utility of existing features.

I will focus on the first big barrier for wealth to be produced.

Turbidostat-based development

A classic business response to the Testing/DevOps class of failures is to slow down development so that software stay in a state that is only so broken. The more brokenness is observed, the less features are allowed.

This makes software development to follow turbidostat model. What is turbidostat? When you grow microorganisms in a continuous fashion, you can limit their numbers in various ways. One of them is to have a device that optically monitors the content of your bioreactor and manages replacement of the content based on turbidity, on the amount of light that passes through the medium.

In the analogy I’m introducing, the device measuring turbidity is a manager or a collective of managers that observe outages and bugs. When is turbidity low / when there are many outages, both planned and existing features/products have to go, replaced by an empty space of “this is not supported” or “it’s really better that it ‘works’ this way”.

You won’t hear anyone to state the behavior like this, but the enterprise cycle of “build-maintain-obsolete” is very much caused by the need to throw away functionality without stating it aloud. By saying “we will replace the older version by this new product that will allow us to do X”, it’s not actually stated what is being lost and the proposition sounds productive and optimistic.

The less extreme variants of turbidostat-induced behavior is picking features not based on the business need, but based on safety of their implementation. The more fragile product, the less are customer needs for progress respected, the more is pure survival and doing cosmetic changes recognized as success.

In some extreme instances, customers frightened by recent experiences with your product will actually stop asking for everything else than “just don’t break it this month”. That doesn’t mean they won’t be better with more functionality – you just made them part of your turbidostat.

The culture of the organization plays big role in whether is outage or bug perceived as a bigger problem than lost opportunity of similar magnitude. If your company stress people for outages and not for not seizing opportunities, you will get mightily magnified effects of turbidostatic development.

A call to change the rules of the game

The turbidostat mental model completely misses the option to make changes in the relationship between features and bugs. Is it necessary for every new piece of much needed code to break other stuff? Is there a fixed ratio of screw-ups to successes we can’t possibly escape?

By proper application of continuous deployment, impact of code-induced outages can be lowered significantly. By proper application of automated testing at multiple levels of system integration, you can get much lower rate of bugs in your production and also much shorter feedback loop for your developers to fix them.

This is why are testing and DevOps primary technical ways to get out of zero-sum game of turbidostat-based development.

There is a space for more wealth to be created by software, there is a way to break the karmic cycle of rewriting everything every couple of years. We don’t need to kill mature products by much simpler versions under the rouse of “we will make it better this time” that actually means “we want to get rid of the functionality we can’t handle”.

We not only should, but also can add new behaviors boldly.