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 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
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.
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.
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.
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.
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.