If and only if
Single-level feature flags are really useful for testing small, discrete parts of your infrastructure or software. It’s easy to understand what is happening when you use them, and it’s easy to control who has access to them. But sometimes they don’t offer you the complexity you need to solve your problems.
Adding levels of hierarchy to your feature flags allows you to manage flags as bundles or to set control levels differently for different environments, and to make flags conditional on the state of other flags. With this level of abstraction, you can be even more confident that you are delivering the software experience you intend, and only when you want to deliver it.
When you create a new flag, one of your options is to make it dependent on an existing flag (or flags) by setting a prerequisite flag. Your new flag will check this prerequisite flag rule before any other targeting rule.
In this example, if the example flag is on (and we can see here that it is), then when you turn the targeting on for the new flag, the new flag will appear to all the targets.
In the next example, the prerequisite flag is off, so it doesn’t matter what value is provided by the multivariate. Your new rule will only execute its targeting rules if the prerequisite flag is on AND the value is “d”.
Think of the rules logic as a top-down decision, where each branch has the ability to stop further decision-making or targeting and return the default rule.
Flag hierarchy in action
One common use case for prerequisite flags is to bundle a set of flags together to release all at once. Imagine a company is working on a major feature like mobile deposit—different teams are working on camera control, OCR, check verification, and banking transactions. None of those features makes sense in isolation from the others, but having one big flag that controls everything means that all the teams have to work together at the same time, and if anyone makes a mistake about the flag, everything might be released prematurely.
Instead, the team leads set up flags for each of the sub-features, and all of the sub-features have a prerequisite flag called Mobile_Deposit. The Mobile_Deposit flag is turned on in the test environment, but only the overall project manager can turn it on in production. Each team works on their sub-feature, and uses tests to check the code they are responsible for works correctly. As they go, they can test against the other sub-features as they become ready and their flags are turned on.
The sub-feature teams can decide when to turn on the flags for their feature, but not for other teams. When all of the testing is completed and the project manager is confident in the product, they can turn on all the sub-features in production. Then, rather than assume everything will work perfectly, they can use the Mobile_Deposit prerequisite flag to progressively deliver the feature. Only 2% of users will see the feature the first day, and the teams can watch the analytics from live data to make sure everything is performing as expected. None of the sub-feature flags needs to be adjusted to do this, since the prerequisite flag is controlling the percentage rollout.
When the feature is fully rolled out and has soaked in production, the teams can remove the flags from the code that control the sub-features as well as the prerequisite flag.
We’ve described more of the process and theory of controlling flags with other flags in the Flag Hierarchy Guide (coming soon!). If you’re interested in creating your own flags or experimenting with flag dependencies, you can sign up for a LaunchDarkly free trial, or play with our Glitch app.