"Feature Toggling" is a set of patterns which can help a team to deliver new functionality to users rapidly but safely. In this article on Feature Toggling we'll start off with a short story showing some typical scenarios where Feature Toggles are helpful. Then we'll dig into the details, covering specific patterns and practices which will help a team succeed with Feature Toggles.

Feature Toggles are also refered to as Feature Flags, Feature Bits, or Feature Flippers. These are all synonyms for the same set of techniques. Throughout this article I'll use feature toggles and feature flags interchangebly.

A Toggling Tale

Picture the scene. You're on one of several teams working on a sophisticated town planning simulation game. Your team is responsible for the core simulation engine. You have been tasked with increasing the efficiency of the Spline Reticulation algorithm. You know this will require a fairly large overhaul of the implementation which will take several weeks. Meanwhile other members of your team will need to continue some ongoing work on related areas of the codebase.

You want to avoid branching for this work if at all possible, based on previous painful experiences of merging long-lived branches in the past. Instead, you decide that the entire team will continue to work on trunk, but the developers working on the Spline Reticulation improvements will use a Feature Toggle to prevent their work from impacting the rest of the team or destabilizing the codebase.

The birth of a Feature Flag Here's the first change introduced by the pair working on the algorithm: before function reticulateSplines(){ // current implementation lives here } these examples all use JavaScript ES2015 after function reticulateSplines(){ var useNewAlgorithm = false; // useNewAlgorithm = true; // UNCOMMENT IF YOU ARE WORKING ON THE NEW SR ALGORITHM if( useNewAlgorithm ){ return enhancedSplineReticulation(); }else{ return oldFashionedSplineReticulation(); } } function oldFashionedSplineReticulation(){ // current implementation lives here } function enhancedSplineReticulation(){ // TODO: implement better SR algorithm } The pair have moved the current algorithm implementation into an oldFashionedSplineReticulation function, and turned reticulateSplines into a Toggle Point. Now if someone is working on the new algorithm they can enable the "use new Algorithm" Feature by uncommenting the useNewAlgorithm = true line.

Making a flag dynamic A few hours pass and the pair are ready to run their new algorithm through some of the simulation engine's integration tests. They also want to exercise the old algorithm in the same integration test run. They'll need to be able to enable or disable the Feature dynamically, which means it's time to move on from the clunky mechanism of commenting or uncommenting that useNewAlgorithm = true line: function reticulateSplines(){ if( featureIsEnabled("use-new-SR-algorithm") ){ return enhancedSplineReticulation(); }else{ return oldFashionedSplineReticulation(); } } We've now introduced a featureIsEnabled function, a Toggle Router which can be used to dynamically control which codepath is live. There are many ways to implement a Toggle Router, varying from a simple in-memory store to a highly sophisticated distributed system with a fancy UI. For now we'll start with a very simple system: function createToggleRouter(featureConfig){ return { setFeature(featureName,isEnabled){ featureConfig[featureName] = isEnabled; }, featureIsEnabled(featureName){ return featureConfig[featureName]; } }; } note that we're using ES2015's method shorthand We can create a new toggle router based on some default configuration - perhaps read in from a config file - but we can also dynamically toggle a feature on or off. This allows automated tests to verify both sides of a toggled feature: describe( 'spline reticulation', function(){ let toggleRouter; let simulationEngine; beforeEach(function(){ toggleRouter = createToggleRouter(); simulationEngine = createSimulationEngine({toggleRouter:toggleRouter}); }); it('works correctly with old algorithm', function(){ // Given toggleRouter.setFeature("use-new-SR-algorithm",false); // When const result = simulationEngine.doSomethingWhichInvolvesSplineReticulation(); // Then verifySplineReticulation(result); }); it('works correctly with new algorithm', function(){ // Given toggleRouter.setFeature("use-new-SR-algorithm",true); // When const result = simulationEngine.doSomethingWhichInvolvesSplineReticulation(); // Then verifySplineReticulation(result); }); });

Getting ready to release More time passes and the team believe their new algorithm is feature-complete. To confirm this they have been modifying their higher-level automated tests so that they exercise the system both with the feature off and with it on. The team also wants to do some manual exploratory testing to ensure everything works as expected - Spline Reticulation is a critical part of the system's behavior, after all. To perform manual testing of a feature which hasn't yet been verified as ready for general use we need to be able to have the feature Off for our general user base in production but be able to turn it On for internal users. There are a lot of different approaches to achieve this goal: Have the Toggle Router make decisions based on a Toggle Configuration , and make that configuration environment-specific. Only turn the new feature on in a pre-production environment.

, and make that configuration environment-specific. Only turn the new feature on in a pre-production environment. Allow Toggle Configuration to be modified at runtime via some form of admin UI. Use that admin UI to turn the new feature on a test environment.

Teach the Toggle Router how to make dynamic, per-request toggling decisions. These decisions take Toggle Context into account, for example by looking for a special cookie or HTTP header. Usually Toggle Context is used as a proxy for identifying the user making the request. (We'll be digging into these approaches in more detail later on, so don't worry if some of these concepts are new to you.) The team decides to go with a per-request Toggle Router since it gives them a lot of flexibility. The team particularly appreciate that this will allow them to test their new algorithm without needing a separate testing environment. Instead they can simply turn the algorithm on in their production environment but only for internal users (as detected via a special cookie). The team can now turn that cookie on for themselves and verify that the new feature performs as expected.

Canary releasing The new Spline Reticulation algorithm is looking good based on the exploratory testing done so far. However since it's such a critical part of the game's simulation engine there remains some reluctance to turn this feature on for all users. The team decide to use their Feature Flag infrastructure to perform a Canary Release, only turning the new feature on for a small percentage of their total userbase - a "canary" cohort. The team enhance the Toggle Router by teaching it the concept of user cohorts - groups of users who consistently experience a feature as always being On or Off. A cohort of canary users is created via a random sampling of 1% of the user base - perhaps using a modulo of user ID. This canary cohort will consistently have the feature turned on, while the other 99% of the user base remain using the old algorithm. Key business metrics (user engagement, total revenue earned, etc) are monitored for both groups to gain confidence that the new algorithm does not negatively impact user behavior. Once the team are confident that the new feature has no ill effects they modify their Toggle Configuration to turn it on for the entire user base.

A/B testing The team's product manager learns about this approach and is quite excited. She suggests that the team use a similar mechanism to perform some A/B testing. There's been a long-running debate as to whether modifying the crime rate algorithm to take pollution levels into account would increase or decrease the game's playability. They now have the ability to settle the debate using data. They plan to roll out a cheap implementation which captures the essence of the idea, controlled with a Feature Flag. They will turn the feature on for a reasonably large cohort of users, then study how those users behave compared to a "control" cohort. This approach will allow the team to resolve contentious product debates based on data, rather than HiPPOs.

This brief scenario is intended to illustrate both the basic concept of Feature Toggling but also to highlight how many different applications this core capability can have. Now that we've seen some examples of those applications let's dig a little deeper. We'll explore different categories of toggles and see what makes them different. We'll cover how to write maintainable toggle code, and finally share practices to avoid some of pitfalls of a feature-toggled system.