Feature Toggles (Feature Switches or Feature Flags) vs Feature Branches

This article is part of the Continuous Integration, Delivery and Deployment series.

Feature Branches

If you are using branches, you are not doing Continuous Integration/Deployment/Delivery!

You might have great Code Coverage with unit tests, you might be doing TDD, you might have functional and integrations tests written in BDD format and you might run all of them on every commit to the repository. However, if you are having branches, integration is delayed until they are merged and that means that there is no continuous integration.

People tend to like feature branches. They provide flexibility to decide what to release and when. All there is to do is to merge features that will be released into the main branch and deploy to production. The problem with this approach is the delay. Integration is delayed until the merge. We cannot know whether all those separately developed features work well together until the merge is done and all the unit, functional, integration and manual tests are run. On top of that, there is the problem caused with the pain of merge itself. Days, weeks or even months of work are suddenly merged into the main branch and from there to all not-yet-to-be-released branches. The idea of Continuous Integration is to detect problems as soon as possible. Minimum delay until problems are found.

The most common way to mitigate this problem is to have feature branches small and short-lived. They can be merged into the main branch after only a day or two. However, in many cases this is simply not possible. Feature might be too big to be developed in only few days. Business might require us to release it only in conjunction with other features.

In other words, feature branches are great for allowing us to decide what to release and when. They provide us the flexibility but they prevent us from doing Continuous Integration. If there would be only one branch, we could do continuous integration but the release problems that were solved with feature branches would come back to haunt us.

Feature Toggles

Feature Toggles (sometimes called Feature Switches or Feature Flags) should solve the need to be able to deploy only selected set of features while keeping only one (main) branch. With them we can do all the work in one branch, have continuous integration taking care of the quality of our code and use flags to turn features off until they are ready to be released. We can have all the benefits of Continuous Integration together with the flexibility to choose which features will be available and which will be hidden. Moreover, it is a step towards Continuous Deployment. If we do have satisfying automated test coverage and can switch features off and on, there is nothing really preventing us from deploying to production each commit that passed all verification. Even if some bug sneaks into the production, with Feature Toggles it would be very easy to turn that feature off until it’s fixed.

The basic idea is to have a configuration file that defines toggles for features that are pending to be fully released. Alternative to a configuration file can be a database table. The application should use those toggles to decide whether to make some feature available to the users or not. They might even be used to display some functionality to a subset of users based on their role, geographic location or random sample.

There are only few rules to be followed:

  • Use toggles only until they are fully deployed and proven to work. Otherwise, you might end up with “spaghetti code” full of if/else statements containing old toggles that are not in use any more.
  • Do not spend too much time testing toggles. It is in most cases enough to confirm that the entry point into some new feature is not visible. That can be, for example, link to that new feature.
  • Do not overuse toggles. Do not use them when there is no need for them. For example, you might be developing a new screen that is accessible through the link in the home page. If that link is added at the end, there might be no need to have toggle that hides it.

Examples

There are many libraries that provide the solution for Feature Toggles. However, implementing them is so easy that you might choose to do it yourself.

Here are few examples of possible implementations of Feature Toggles. They use AngularJS but the logic behind them could be applied to any other language or framework.

[JSON with Feature Toggles]

{
  "feature1": {
    "displayed": false
  },
  "feature2": {
    "displayed": true
  },
  "feature3": {
    "displayed": false
  }
}

I tend to have more values in my toggles JSON. Some of them as disabled, description, allowed_users, etc. The above example is only the bare bones minimal solution.

Next, we should load the JSON into, in this example, AngularJS scope.

[AngularJS that loads Feature Toggles into the scope]

$http.get('/api/v1/data/features').then(function(response) {
  $scope.features = response.data;
});

Once Feature Toggles are in the scope, the rest is fairly easy. Following AngularJS example hides the feature when displayed is set to false.

[AngularJS HTML that hides some element]

<div ng-show="features.feature1.displayed">
  <!--Feature HTML-->
</div>

In some cases, you might be working on a completely new screen that will replace the old one. In that scenario something like the following might be the solution.

[AngularJS that returns URL depending on Feature Toggle]

$scope.getMyUrl = function() {
  if($scope.features.feature2.displayed) {
    return 'myNewUrl';
  } else {
    return 'myOldUrl';
  }
}

Then, from the HTML, it would be something like the example below.

[AngularJS HTML that toggles URL]

<a href="{{getMyUrl()}}">
  This link leads somewhere
</a>

In some other cases change might be on the server. Following REST API best practices, you’d create a new API version and use Feature Toggle to decide which one to use. Code could be like following.

[AngularJS that performs request that depends on Feature Toggle]

var apiUrl;
if($scope.features.feature2.displayed) {
  apiUrl = '/api/v2/myFancyFeature';
} else {
  apiUrl = '/api/v1/myFancyFeature';
}
$http.get(apiUrl).then(function(response) {
  // Do something with the response
});

Same logic applied to the front-end could be applied to the back-end or any other type of the application. In most cases it boils down to simple if/else statements.

Advertisements

13 thoughts on “Feature Toggles (Feature Switches or Feature Flags) vs Feature Branches

  1. griffinfujioka

    I’m unclear of where to load the feature toggles into scope. Can this be in any JavaScript file?

    Reply
  2. Cristian Garcia

    I disagree, making feature branches isn’t a delay, if you go that far, even working with the repository itself is a delay because you work at your local until you commit/push your code!

    The question is how you use the feature branches.

    Reply
    1. Viktor Farcic Post author

      I agree that the question is how you use the feature branches. If you merge them often (to define what means often), they are great. If you wait for a long time, you are delaying integration. It all depends on the context but I’d say that waiting more than a day to merge a branch with the master is too much in the context of continuous integration/delivery. That does not mean that it’s bad to delay the merge, just that it is not in the spirit of CI/CD.

      Reply
  3. Tino de Bruijn

    There is a big problem with feature toggles though, which is that they increase the possible execution paths of your code by a factor two, and therefore also the amount tests you have to run. If you want to be sure your code works with all N toggles, you have to run your tests N^2 times! Sometimes it might just be easier to create a branch and make sure you CI server tests it.

    Reply
    1. Viktor Farcic Post author

      Execution paths are increased but not by factor of two. To begin with, feature toggles should not be used for every feature but only those that can not be developed fast and need to be hidden. In that new feature, usually only an entry point has the flag, not all the code. Also, toggles should be removed as soon as they are not needed.

      In any case, feature toggles are only one more tool we can use and, as anything else, there are cases when they are useful and cases when they are not. It up to us to decide on case by case basis.

      Reply
  4. Pingback: Cómo usan #Git en GitHub – #scbcn – Codely.TV

  5. Pingback: FEATURE TOGGLES (FEATURE SWITCHES OR FEATURE FLAGS) VS FEATURE BRANCHES | IndaSoft

  6. Pingback: Feature Toggles (Feature Switches or Feature Flags) vs Feature Branches – Feature Flags, Toggles, Controls

  7. Pingback: Feature Toggles (Feature Switches or Feature Flags) vs Feature Branches – Feature Flags, Toggles, Controls

  8. Yair Even Or

    I can understand how it could be set-up for small features, but what is there is a new feature which requires a screen re-design (html, css & js changes).. how can that be simply “toggled” ?

    also what if the new feature is dependent on updating a version of some library that will most likely affect other components in the system? I think many cases needs to be addressed, since approaching them is not easy as changing some flag somewhere..

    Reply
  9. Viktor Farcic Post author

    In the scenario you mention, you would probably build a new screen and there wouldn’t be a need for feature toggles. Your UX testers would simply open it directly.

    Like anything else, feature toggles are only one more tool in a toolbelt. It’s up to you to decide when to use them and when not. We should never approach things as rules written in stone. If something makes sense for some use case, use it. if it doesn’t, use something else.

    Reply

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s