Article

15min read

Feature Toggles: Types & Best Practices

Feature toggles are among the most powerful methods to support continuous integration and continuous delivery (CI/CD). Feature toggles —sometimes called feature flags— are a method for modifying features at runtime without modifying code.

Developers can create feature toggles by coding a “decision point” where the system runs a given feature depending on whether specified conditions are met. In other words, feature toggles allow you to quickly and efficiently deliver context-sensitive software.

Feature toggles have a wide range of possible applications for everything from supporting agile development, to market testing, to streamlining ongoing operations. However, with this power comes the potential for introducing unnecessary complexity into your code. You need to properly manage feature toggles to get the most from them.

In this article, we’ll give you an overview of precisely what feature toggles can do, how you can implement them in your development and production environments, and share some of our own recommended best practices for using them.

[toc]

 

What exactly is a feature toggle?

In the simplest possible case, a feature toggle is a powerful “if” statement, from which at least one of two different codepaths is followed at runtime depending on a condition or conditions provided. Here is a straightforward example:


normalFeature = {
  'id': 1,
  'description': 'basic service',
  'newstuff': False
}
testFeature = {
  'id': 2,
  'description': 'much better service',
  'newstuff': True
}
@app.route('/ourapp/api/v1.1/storefront', methods=['GET'])
def get_tasks():
if internalTester == True:
return jsonify({'feature': testFeature})
else:
return jsonify({'feature': normalFeature})

In this Python code sample, we have defined two different, generic features: normalFeature and testFeature. At runtime, the application checks in configuration to see whether an internal test user is loading it. If so, the application loads the test feature under development. If not, the regular customer sees the current feature.

To see how to code flags in specific programming languages, read for instance: “How to set up feature flags in a React js app”.

Feature toggles testing
Example of a feature toggle controlling two codepaths (Source)

Feature toggles can be anything from a simple “if” statement to complex decision trees, which act upon many different variables. A wide variety of conditions, including fitness test results from other features in the codebase, a setting in feature management software, or a variable provided by a config file, can be used to determine which way a toggle flips.

Different feature toggles for different tasks

You should manage feature toggles differently depending on how you deploy them. One useful way to think about toggles is to break them down into categories across two dimensions: their longevity in your development and operational processes and how dynamic their function is. Considered this way, we can break feature toggles out into four different categories:

  • Release toggles
  • Experimental toggles
  • Operational toggles
  • Permission toggles
Chart four feature toggle categories
A chart of the four feature toggle categories (Source)

Release toggles

These toggles support dev teams as they write new features. Instead of creating a branch where the team will write the new feature, they generate a release toggle in the master codebase that leaves their code inactive while they work on it. They can still push that trunk code to production to meet delivery targets.

Release toggles usually aren’t meant to be permanent fixtures in your codebase. You should remove them once their associated feature is complete. In practice, this usually means they have a lifecycle of a few days to a few weeks, which puts them lower on the longevity scale. Release toggles also tend not to be very dynamic. Either the feature is ready for release, or it isn’t.

Release toggle example

An e-commerce company has a new configurator tool in development at the request of one high-profile customer. The configurator monitors items the customer has already selected for a built-out and suggests item sets to complete their order.

The company eventually wants to roll out that feature to all customers, but for now, the configurator only works within that one customer’s specifications. The configurator’s dev team enables a release toggle for this new feature that keeps it inactive.

Experiment toggles

These toggles are used to facilitate A/B testing or multivariable testing. You create a toggle point beyond which the different features you want to test are down two or more different code paths. At runtime, the system —or the toggle itself— splits users into different cohorts and exposes them to the different features.

Tracking aggregate experience data for each cohort will allow you to compare these different features’ effects. Experiment toggles are popular methods for optimizing marketing efforts, user experiences, and other user-facing features.

Usually, experiment toggles should only exist as long as data needs to be gathered for feature testing. The exact timeframe will depend on traffic volume to that feature, but typically that means on the order of several weeks to several months. This constraint is more about the test itself than the toggle. The value of the data collected will diminish over time as other feature and code updates invalidate comparisons to earlier gathered user data.

Experiment toggle example

Our e-commerce company has finished debugging its new configurator, but there is some debate over which of the two suggestion algorithms provides the best experience. They decide to set up an A/B test to get some real-world data.

They add an experiment toggle to the production configurator with the two different suggestion algorithms behind it. The toggle splits users into two cohorts with a modulo when they try loading the configurator. After three weeks, the team feels they have conclusive data showing more users complete their orders using the B algorithm. The e-commerce company removes the experiment toggle, and that algorithm goes live for all users.

A/B Testing
A/B test example (Source)

Operational toggles

Operational (Ops) toggles are used to turn features off —like a “kill switch“— or otherwise adjust their performance. For example, if certain conditions are not met, such as KPI targets dipping below a threshold, the toggle turns that feature off until conditions improve. Operational toggles are useful to code in front of new features just out of testing or in front of resource-intensive features.

The longevity of ops toggles varies depending on their specific use case. If you’re using one to regulate a new feature just out of development, you probably only need the toggle in place for a couple of months. On the other hand, a kill switch toggle is usually designed to be a permanent code fixture. Ops toggles usually are as static or dynamic as the conditions under which the feature they control will operate. For example, ops toggles tied to just one performance metric tend to be relatively static.

Operational toggle example

Our e-commerce company is preparing for a spike in traffic ahead of their popular annual sale. This will be the first such sale with the configurator in production. During testing, devs noticed the user-preferred B algorithm was a little greedy with system resources.

The operators ask for a kill switch to be coded for the configurator before the sale goes live. They just want a single toggle they need to click in their release management software should performance degrade. Lo and behold, on the first day of the sale, the configurator begins to degrade performance, and ops staff quickly kill it before too many users notice.

Permission toggles

Permission toggles are intended to be longer-lived or even permanent fixtures in your code. They are used as a method to make features available to specific subsets of users. For example, you might use a permission toggle to show premium content only to premium users logged into your site. Permission toggles tend to be the most dynamic of the four categories defined here, as they usually trigger on a per-user basis.

Permission toggle example

The simple example at the beginning of this article is close to what a permission toggle might look like. After the annual sale is complete, our e-commerce company decides algorithm B is too resource-intensive to make it available to their entire user population. Instead, they decide to make it a premium feature.

Feature toggles vs. feature flags

As a brief aside, there is some debate over the name feature toggle as opposed to feature flag. “Toggle” is a more appropriate name when code is turned on or off for a few major code branches. “Flag” is a more appropriate term if a decision point is followed by a very multi-conditional or broad set of codepaths.

Including feature toggles in your roadmap supports agile workflows

Applying feature toggles to your development process supports newer agile approaches. You can release software even while code sprints on new features are still in progress. Those features just need to be hidden behind toggles until they’re ready for release, market testing, or whatever the next stage in their development is.

You would usually write the user’s newly requested features on code branches under more traditional waterfall development models. Those features would then go through a lengthy testing and QA process before your team could integrate them back into trunk code. Using feature toggles, you can perform the entire development and testing process right on trunk code.

Our best practices for using feature toggles

As we’ve discussed, feature toggles are a powerful and flexible development method. If you don’t carefully implement and manage your toggles, they can quickly lead to a messy codebase or increased technical debt.

Many different best practices for coding feature toggles have been proposed, but we wanted to offer some of our own. Once one messy decision point is written into your codebase, many more seem to follow. Applying these best practices from the start will help keep problems like that in check.

Website code
Website code under development (Source)

Use feature toggles to gradually transition to agile development

If your team wants to try out agile development and testing methodologies without jumping entirely into a new development methodology, then introducing feature toggles into your roadmap is an excellent place to start. The cost to try them out is low. You could just have one team try using an experimental toggle for a single canary deployment they’re working on, for example.

If the trial goes well, you can replace that experimental toggle with an ops toggle when the feature goes into production. Then expand toggle use to other teams or other processes from there. Introduce them earlier in development cycles as release toggles. Then, slowly but surely, you’ll be on your way to full agile development.

Use toggles for both internal and external features

As should be clear by now, feature toggles have uses throughout the development and production lifecycle of your software. Don’t limit your toggle usage to just customer-visible features. You can use release and operational toggles to manage backend features too. They give DevOps teams a very granular level of control and risk management over code, which can be important when modifying backend features that have a wide-ranging impact on how your system performs.

Include toggle planning in your design phase

Everything from toggle naming, configuration settings, removal processes, and access control trickles down from how you first feature design new features. Build that toggle planning into your design process, and feature management six months from now will be greatly simplified.

Have a standardized toggle naming scheme

Many organizations use a style guide to regulate how developers write and organize code. For example, how they employ everything from spacing, ordering, and parentheses, to naming. If you’re going to use feature toggles, you should also standardize your naming style early in your toggle adoption process.

Brevity is essential in other aspects of coding, but when it comes to toggle names, be verbose. Detail means clarity. Verbose toggle names help devs and ops staff outside your core understand what they’re looking at when their only reference is the toggle name you chose on a whim six months ago.

Some other toggle naming conventions we suggest adopting include:

  • Include the team or the project name.
  • Include the toggle’s creation date.
  • Identify the flag’s category.
  • Be descriptive of the toggle’s actual behavior.

Here is an example: algteam_10-12-2021_Ops_configurator-killswitch

This name gives some useful information someone on any team can use to understand what they’re looking at when a toggle is called in an error message. They know who wrote the toggle, how long it has been sitting in the codebase, and what the toggle does.

Keep reading: Best practices to name your feature flags.

Manage different toggles differently

This practice sounds self-evident, but it is an important point to underline. As we discussed above, feature toggles can be divided into four general categories. You should manage each of those four categories differently.

Think about our configurator example from earlier as it moved from development to market testing to operational management. The configurator code sat behind a feature toggle of one kind or another the entire time. But the way the development and product teams interact with that toggle needs to change at every stage.

During early development, the toggle might just be configured in source control. Then while the e-commerce company is doing A/B testing, the toggle might be in a feature management platform. When the ops team adds a kill switch, they may decide they want it in the same feature management platform but on a different dashboard.

Manage your feature flags at scale

Always expose feature toggle configurations

As with any other code object, it is beneficial to document feature toggle configurations as metadata, so other developers, testers, and production staff have a “paper trail” they can follow to understand precisely how your feature toggle runs in a given environment. Ideally, store your toggle configurations in a human-readable format so that it is easy for people outside your team to understand what a toggle does.

This best practice is beneficial for features you expect to be toggled for a long time. Think about our configurator example again. A brand new product operator trying to understand a sudden, unexpected performance slowdown will be very grateful to have a human-readable file explaining that the B algorithm was surprisingly resource-intensive in testing a year earlier.

Keep the holding costs of feature toggles in check

When first using feature toggles, try to resist the temptation to use them everywhere in your code all at once. While feature toggles are easy to create, their use requires proper management and testing to realize any benefit. Scale up your feature toggle usage slowly, or consider integrating a feature management platform into your development and testing environments.

Deploy feature toggles strategically and keep your inventory of toggles as low as possible. Use them wherever necessary, but make sure there is a process for vetting whether toggles are the appropriate method for solving a particular problem.

Don’t let old toggles hang around in your code. Prune them as soon as their lifecycle has run its course. The more idle toggles your code has, the greater the management overhead that falls on your team. You can manage toggle removal by adding code cleanup tasks to your team’s backlog or building the process into your management platform.

Developer features toggles

Keep toggle scope as small as possible

Since toggling can be so powerful, it is often tempting to put large swaths of code under the control of a complex series of toggles. Resist this urge and keep feature toggling within as small a scope as possible to complete any given task.

If a toggle overlaps more than one feature at a time, it can be confusing for the rest of your team and a nightmare to debug weeks or months down the road when it begins to impact other teams’ work.

Consider our configurator example again. Our dev team is building four separate widgets that users will manipulate within the configurator tool. In this scenario, we would recommend setting up five toggles: one for the configurator itself and one for each widget. Code the widget toggles with a dependency on the configurator toggle. In this framework, if one of the widgets fails to load correctly, the others will still be served to the user.

Feature toggles can transform your entire development process

Feature toggles are powerful methods for developing, testing, and operating code features within a continuous integration and continuous delivery framework. They are a simple method that helps your team deliver higher quality, more stable code according to agile principles.

In this article, we walked through how feature toggles work, what types of toggles you can create, and how you can employ them in your agile process — or try them out in any development process. We also shared some of our recommended best practices for making sure your company gets the most from using feature toggles.

Start small and scale up

There is no reason you can’t start using feature toggles today. Start small and scale up your usage as your team gets comfortable with how they work. If you’re starting to code a brand new feature from your backlog, consider setting up a release toggle in trunk code, so you don’t have to branch. If you’re beginning market testing, consider setting up an experiment toggle for some split testing.

Once your team has a good handle on how they want to use feature toggles, consider whether a feature management platform can streamline their administration. Streamlining development and testing was what we had in mind when we developed our release and feature management platform.

AB Tasty allows your team to use a single tool to streamline toggle workflows and communication. Regardless of a team’s tasks or focus, our feature management product has everything it takes to deliver the right features in the right way.

Subscribe to
our Newsletter

bloc Newsletter EN

We will process and store your personal data to send you communications as described in our  Privacy Policy.

Article

8min read

What Does Feature Rollback Mean and How To Do It

When it comes to feature testing, you’re in a bind.

On the one hand, you need real-world data and feedback from real-world users. You know that every new feature you develop is, at best, an educated guess about what your real-world users want from you. No matter how educated that guess might be, and no matter much internal validation you perform, you can only generate meaningful data and feedback on each new feature you develop by releasing it to real-world users to test out in their real-world environments.

On the other hand, it’s risky to give real-world users an unproven feature. You know that every new feature you release might have something wrong with it. Maybe there’s a technical issue you missed during development. Maybe it just doesn’t align to user expectations as closely as you hoped. No matter the issue, releasing an unproven feature can cause real harm to your brand’s user relationships.

This is a tricky problem and one that is never going to be fully solved. But, thankfully, there are methods you can follow to minimize the problem, and collect real-world data and feedback while mitigating the impact when something (inevitably) goes wrong. 

In this piece, we’ll explore one of these methods— rollbacks. 

What is a Feature Rollback?

It’s a simple practice, with powerful implications.

When you perform a rollback, you take some code out of a live environment. Back in the day rollbacks could be truly massive. Software products used to be updated in giant new releases that could include a wide range of changes— including multiple new features and significant changes to existing features. If one of these huge releases had some fatal bugs in it, or just wasn’t well-received by users, then the entire thing might need to be rolled back (even if the issues were contained within just a few elements of the release).

All of this has changed with the adoption of Agile methodology. Releases keep getting smaller and more incremental, and so do rollbacks. Most modern Product Managers have adopted phased release plans, where they only release a single new or upgraded feature at a time— and often only to individual segments. And when modern Product Managers do release multiple new or upgraded features at once, the different features are separate from each other.

This evolution has changed the way rollbacks happen. After a new release, Product Managers can now isolate the individual feature(s) that have proven unfit for live usage and perform a targeted rollback on them, and them alone. The whole rollback process is now much faster, much nimbler, much more precise— and delivers much greater benefits.

Why Should Product Managers Perform Rollbacks?

When a Product Manager properly structures and deploys rollbacks, they improve their ability to test new features in a real-world environment with real-world users with a minimal level of risk. An imperfect feature is no longer the end of the world. If a feature has development issues or poor alignment with user requirements, you can perform a rollback and remove it from a live environment in real-time with just one click.

For Product Managers, this changes the game. The more mature your rollback capability, the more you can afford to make mistakes. Your risk shrinks, giving you the freedom to test more features with more users earlier in the development cycle, ultimately leading you to iterate your products faster and faster.

Now, rollbacks are not a silver bullet. They don’t absolve you from doing everything you can to develop the highest-quality features possible before you test them. But rollbacks allow you to test new features with greater confidence and reduced concerns about creating problems for your users. 

When Should You Perform a Rollback? Two Common Use Cases

For most Product Managers, there are two common use cases why you might need to perform a rollback.

Rollback Use Case 1: Your Feature has a Bug

This first use case is pretty self-explanatory.

You might have the most robust and thorough QA and testing processes in the world. It’s still highly likely your new features will still have one or more bugs in them when you release them into a live environment. Maybe they’re issues you just didn’t think to search for or didn’t know how to search. Maybe they’re issues that only show up in live environment after hundreds of real-world users tool around with the feature.

Regardless of the reason, if significant technical issues pop up in your new feature, then you’ll likely want to perform a rollback on that feature to fix it. With the right rollback process, you can react to these errors in near-real-time and remove the feature—and maybe even fix it—in minutes before it impacts too many users. 

Rollback Use Case 2: Your Feature is Poorly Received

This second use case is a little more sophisticated.

Essentially, after you release a new feature you monitor how users respond to it, and how well it’s hitting your business KPIs. If your new feature is not performing as expected, and is generating negative usage data and user feedback, then you can perform a rollback to remove it from its live environment. If it isn’t hitting—or at least tracking towards—its business goals, then it might not be worth keeping live.

After you roll back your feature, you can either utilize the data and feedback you collected to fix the feature and help it better align to user expectations and business requirements, or you can decide that the feature was fundamentally misguided and just needs to be retired.  

With the right rollback process, you can also review and respond to the usage data and user feedback you receive in near-real-time, and prevent too many users from getting too disgruntled about receiving a feature that misses the mark.

What Do These Two Use Cases Have in Common?

In one word: speed. 

In both use cases, rollbacks are most effective—and mitigate the most risk—when you are able to first monitor feature performance in real-time, to then translate that performance into a quick “yes/no” decision to rollback (or not), and finally to execute on that rollback decision as rapidly as possible. 

The faster you can go through this entire process, the lower the chance that you will create a prolonged negative user experience. In some scenarios, the decision to perform a rollback and the execution of that rollback need to happen in minutes. 

It’s a daunting mandate, but here are a few tips to help you meet it.

How to Make Faster Rollback Decisions

It’s challenging to decide—in the moment—whether or not to rollback a feature. Even the best feature release can be complex and chaotic.

There are multiple moving parts to monitor…

There are many different data and feedback points to take into consideration…

And there’s a lot of emotion at play…

You and your team just spent weeks, maybe even months, pouring your blood, sweat, and tears into designing and developing the new feature that you’re testing. If your users love it, then you get that sugar high of knowing you just completed a job well done, and you can just sit back and watch the good data and feedback roll in. But if your users don’t immediately respond as positively as you hoped, then it’s easy to experience an emotional crash and to want to rollback the feature before you even know if the bad response is consistent, let alone what you should do to fix your errors in the next iteration. 

For these reasons, and many more, it’s hard to make the right rollback decision in the moment during a feature release test. Instead, it’s better to make your rollback decisions before you release your new features into the wild.  

Here’s what we mean.

Basically, before you release any new features to any real-world users, you first decide what success and failure looks like for this feature in objective, data-driven terms. 

Then, you decide how much data your release will need to generate before you can make an accurate call about whether the feature is a success or a failure.

Finally, you use these parameters during your release to make objective “yes/no” decisions about whether or not you should rollback your feature at any point. Instead of getting caught up in the moment, you just monitor the performance metrics that you decided were most important, and once they hit the thresholds you set prior to release you simply follow the plan and you either rollback the feature or you don’t— no real-time agonizing required.

How to Execute Rollbacks Faster

In the past, it was near-impossible to perform a rollback quickly from a technical perspective. You needed to have a technical team standing by, waiting to dig into the code to turn off live features, or to revert to a prior state of the entire platform. The entire process was slow, it was labor-intensive, and it took your technical teams away from their valuable development work.  

Software has solved all of these problems. With our own feature management platform, you can rollback a feature in real-time by just toggling a single field with just one click. You don’t need any technical expertise to do so. You don’t need to develop and test a complex rollback process prior to feature release. You don’t even need to think about the technical details— you can save all of that thinking to create the right strategic decision trees that we outlined in the prior section.

AB Tasty also gives you—or any non-technical user—the ability to perform sophisticated feature releases and rollbacks. You can release multiple features at once, monitor how each feature is performing individually, and only rollback the features that aren’t delivering. You can roll out a feature to multiple user segments and only rollback that feature to the individual segments that aren’t responding well to it. We designed our server-side solution to make the execution of rollbacks faster, easier, and far more intuitive than they ever were before.