How we use feature flags
I got some feedback that people want to know what feature flags are.
Wikipedia does a good job of explaining it:
“A feature toggle (also feature switch, feature flag, feature flipper, conditional feature, etc.) is a technique in software development that attempts to provide an alternative to maintaining multiple source-code branches (known as feature branches), such that a feature can be tested even before it is completed and ready for release. Feature toggle is used to hide, enable or disable the feature during run time. For example, during the development process, a developer can enable the feature for testing and disable it for other users.”
Feature flags allows us to deploy functionality that is not complete and activate it once we are happy with our testing or when the outside world is ready for our awesomeness. ;) We use Launch Darkly as our feature flag platform but there are many other platforms and the tips in post are valid for all of them.
If you want to learn more about feature flags in general I recommend When feature flags go bad by Edith Harbaugh from NDC Oslo 2017. Edith is the CEO of Launch Darkly but the talk is about feature flags in general and not Launch Darkly as a product.
To keep track of the feature flags we use we abide by the following rules:
Avoid feature flags if possible
Feature flags increase the complexity of both the code and the testing process which makes is unnecessarily complex for our developers, our testers and our stake holders when doing acceptance testing. Our policy is to only use feature flags when modifying existing functionality and never when implementing new functionality.
There can be only one feature flag per use story/task/bug.
If we have a user story that requires a feature flag we will create a single feature flag for that story and name it “<issue data-preserve-html-node=”true” number=“”>_<description data-preserve-html-node=”true” of=”” flag,=”” *not*=”” description=”” story=“”>”. Our feature flags are always of type bool where false is the default value and represents the code as it was before any changes were made.
We must be notified on changes
If a feature flag is created, removed or changed we will get a notification on Slack in the same channel were we get notifications about production issues. This is done to ensure that at least one person will see that a change has been made.
Lock down flags for a context
The first thing that happens on user interaction in the system is that a session is created (not to be confused with a web session e.g. ASP.NET session state). Everything that happens in the system happens in the context of a session. When the session is created we freeze the values of all flags for that session. This reduces complexity when doing updates as we prevent a session from ending up in a broken state if a feature flag is changed during runtime.
Cleanup old flags
If a user story contains a feature flag we tag that story with a “Cleanup” tag. Cleanup means that once this story is deployed to production we have some cleaning up to do. Once deployed we activate the feature flag and let the system run with the flag enabled for a period of time. During this time the feature flag act as a kill switch. Once the time is up and no issues have been found we delete the feature flag from our code, remove the old code and tests and then re-deploy to production. The actual feature flag is left intact in Launch Darkly. We then let the system run for a week or so before verifying that the feature flag has not been accessed during that time. Once verified we remove the feature flag.
Test both old and new code paths
While a feature flag exist we keep duplicate tests for all code that is affected by the feature flag. One test for when the flag is false and one for when the flag is true. During cleanup, when we remove the flag from our code base, we also remove the old tests (the once were the flag is false).