Agile-based development workflows have become very popular in recent years. Agile development workflows allow teams to quickly iterate during the development process. This allows the teams to integrate code more often and produce deliverables more frequently. A common Git-based agile workflow utilizes feature branches to temporarily isolate developers’ work from each other. However, common guidance states that these feature branches should be short-lived, which means that they need to be integrated into the main branch.
What happens when a feature branch is part of a larger feature that isn’t ready for release? When the work in the feature branch is complete, it must be merged into the main branch. This could pose a problem for code that is a part of a larger feature that may not be ready for release for several months. This is where feature flags come into the picture. In this post, we will explore the benefits of feature flags and how they can be used in a modern development workflow.
What are Feature Flags?
At its most basic, a feature flag is a conditional statement in one or more places that allow a feature to be enabled or disabled. If a configuration value is set to true, then the feature protected by the flag is enabled; if it is set to false, then the feature is disabled.
Feature flags can be as simple or advanced as the use case requires. As mentioned above, a basic flag can be a Boolean on/off value. More advanced flags can enable features for a subset of users based on a percentage chance or the users’ individual settings. The scenarios below go deeper into use cases for feature flags.
Why Should You Use Feature Flags?
Now that you know what feature flags are let’s explore some of the use cases that would drive you to start incorporating feature flags in your application and development workflow.
If a configuration value is set to true, then the feature protected by the flag is enabled; if it is set to false, then the feature is disabled.
Decouple Deployment from Release
The first reason to use feature flags is to decouple the deployment of a feature from the release of the feature. This means that a feature can be deployed, in part or whole, to production without it being available to end-users. The feature flag protects the new code from being invoked until it is fully ready for release. This could be front-end code, like a new page on a website, or new backend code, like a new step in an order processing workflow.
As an example, consider an application that uses a third-party API to pull credit history and scores for loan applicants. The API is called in numerous places across the application for various purposes. The business has signed a contract with a new vendor, and the development team needs to switch the application to use the new API. The development team estimates that switching to the new API will take several weeks of effort, more than can be done in a single sprint. The business also wants the new API implemented as soon as possible so that testing can take place, even though the cutover date is not for six months.
How can the development team implement the calls to the new API, allow them to be tested and compared to the current API by QA, but not actually run them in production? The team utilizes a trunk-based development workflow with short-lived feature branches, so they can’t keep a side branch open for six months until it’s time to cutover to the new API. The team’s answer to the problem is feature flags. They add a feature flag for the API selection to their configuration file. When the application needs to decide which instance of the API interface to instantiate, it looks at the feature flag to determine which one to use. This allows the team to easily switch between the old and new APIs in development and test environments while keeping production on the old API. They can deploy new versions of the code containing the new API integration to production well in advance of the cutover date. When the cutover date finally comes, the team switches the feature flag to enabled and the application switches to the new API without an additional deployment.
Feature flags are also a great tool to use when you want to incrementally roll out a feature to larger and larger portions of your user base. Imagine that you have a new feature ready to be released, but you are concerned that if all your users start using it at the same time, your servers won’t be able to handle the load. You can use a feature flag to wrap the new feature and enable it selectively for 20% of your users. If the servers are keeping up with the load, you can increase the percentage of users who have access to the feature until it is available to all users.
A variation on staged rollouts is using feature flags to perform A/B testing. Feature flags can be used to show 50% of users towards a new landing page and 50% of users the old landing page. From there, records can be kept and analyzed to see which page performed better for conversions.
Opt-In Beta Testers
Feature flags can be made accessible to end-users or groups to allow them to opt-in to new features before they are released to all users. For a great example of this, let’s look at the “Preview features” page in Azure DevOps:
Azure DevOps uses feature flags to manage its new features and UX enhancements. Individual users (or organizations as a whole) can opt into new features before they are rolled out to new customers. When a user enables a preview/beta feature, they provide the development team with real-world testing data. If the user decides they don’t want to continue using the feature until it’s fully released, they have the option to turn it back off – another great data point for the development team.
Permanent feature flags can be used as a method to manage optional add-ons that customers have the option of purchasing. For example, if a customer can purchase additional functionality in a web-based SaaS offering, access to the functionality can be gated by a feature flag. Operationally this is similar to the opt-in beta testers scenario except that the customer does not have direct control over the feature flag.
Using Feature Flags
Feature Flag Lifecycle
Feature flags have their own lifecycle from the time they are introduced to the time they are removed. When possible, the decision to use a feature flag should be made before the first feature branch related to the feature is merged into the main branch. The decision to use a feature flag can be made at any time before it is deployed, but it is easier to implement the sooner the decision is made. Here is a rough lifecycle of a feature flag:
- Decide to use a feature flag to protect a feature.
- Create the feature flag in a configuration location.
- Add conditionals to the code to conditionally expose the feature.
- Follow your development workflow until the feature and flag are deployed to a testing environment.
- Turn the feature flag on and off when necessary to test the feature.
- Follow your workflow until the feature and flag are deployed into production. This may take place across several releases if necessary.
- When the feature is ready to be enabled in production, enable the flag in production.
- If the feature needs to be turned off, the flag can be disabled in production.
- When the feature flag is no longer needed, remove references to it in the code and delete the configuration setting. This will propagate through environments.
More advanced scenarios will complicate this workflow a bit, but the general structure is the same.
Feature Flag Location
There are several options for where to store feature flags. The first is to put them in a configuration file. This can easily be changed in each environment and even live in production. A config file can support staged rollouts to a degree, but it can’t easily support per-user or per-group rollouts.
Feature flags can also be stored in a database. This adds more complexity than a config file, but it also allows you to tie a feature flag to certain application-level users or groups. Using a database can be a good option if you want to do more advanced feature flag scenarios without relying on a third-party service.
The third option for feature flags is to use a third-party feature flag management service. Two examples of this are LaunchDarkly and Azure App Configuration. Both allow feature flags to be defined per-environment and turned on and off at will. They also support the more advanced rollout options.
Feature Flag Candidates
What types of changes should be wrapped by feature flags? The obvious candidate is user-facing changes, such as a new home page or signup workflow. These are great choices for feature flags because they are generally simple to wrap with the flags, and the flags will let you do A/B testing. However, feature flags can be used for a lot more than user-facing changes. Consider the vendor switch from an earlier example. Operational changes like these can also be controlled by feature flags. This allows them to be tested in each environment and allows them to be enabled in production without having to line up a full release for the cutover time.
The purpose of this post was to introduce feature flags and some potential use cases for them. Hopefully, you are interested in integrating feature flags into your development workflow. A future post will show feature flags in action in an ASP.NET Core web application. If you need more assistance with feature flags or any other DevOps or Cloud transformations, contact Tallan to get in touch with our DevOps team.