Feature Flags Guide
Best practices for feature flags
Last updated
Was this helpful?
Best practices for feature flags
Last updated
Was this helpful?
This guide walks through how to quickly add feature flags to your app, and common use cases for feature flags such as randomized rollouts, AB testing, conditional targeting, rollbacks, and more.
Critical Moments has several advantages over other feature flag systems:
Powerful : each flag's logic is evaluated locally on the client in realtime. It can update in real-time based on over 100 properties. Flags can automatically toggle if the battery is low, if the internet connection drops, they set their phone down, and more!
Powerful conditional logic engine: you can write complex conditions combining realtime properties, randomized rollouts, conditional thresholding, and more. You're not bound by sliders and boolean flags.
Free unlimited true/false feature flags: no charge for simple flags
Free for
Completely private : you don't need to trust our server infrastrcture
If you haven't already, follow our to integrate Critical Moments into your app.
Use the in your app to check feature flags values in code.
Progressive Rollouts (or randomized rollouts) are powerful part of using feature flags. When launching a new feature, you can start with a small subset of users, watch for issues. Over time you can rollout to a larger group if everything goes well, or rollback if serious issues are detected.
Here is an example progressive rollout for a feature named feature_name
:
Start at 10%: randForKey('feature_name', stableRand()) % 100 < 10
Increase to 25%: randForKey('feature_name', stableRand()) % 100 < 25
Increase to 50%: randForKey('feature_name', stableRand()) % 100 < 50
Increase to 100%: true
The stableRand and randForKey functions can be used in unlimited feature flags, even on our free plan!
The conditions above work as follows:
stableRand()
: generates a random number, which is always the same on this client, even after app restart.
randForKey(key, randSeed)
: generates a random number which is stable for the key/seed pair. Without adding a unique feature name key for subsequent rollouts, the same users will be selected the same order each time, which is typically not desired for randomized rollouts.
The modulo operator % 100
reduces the large random number to a random number between 0 and 99. Combined with < 25
the check has a 25% chance of being true.
If you do want the users in the same order across different feature flags, simply use the same key in randForKey for those rollouts.
If you find issues when rolling out a feature or want to sunset a feature, you can rollback the flag at anytime with a remote update.
Disabling a feature flag is as easy as pushing a conditional string that will evaluate to false, such as false
.
Unlike other feature flag systems, you can perform targeted rollbacks with over 100 realtime device properties. This is useful if the rollback is only needed for some users. Some examples:
Rollback only iPad: device_model_class != 'iPad'
Rollback only on devices running iOS 15 and earlier versionNumberComponent(os_version, 0) <= 15
Rollback only on older devices (if feature requires higher CPU/GPU/memory): ((device_model_class == 'iPhone' && versionGreaterThan(device_model_version, '13.0') || (device_model_class == 'iPad' && versionGreaterThan(device_model_version, '11.0')))
Feature flags can be used to implement an important part of AB testing: randomized variant assignment. Assigning a user to a AB test variant is very similar progressive rollouts:
Initially 90% in A, 10% in B, (assuming A is proven and B is new/risky): randForKey('experiment_name', stableRand()) % 100 < 90
Scale up to 50/50: randForKey('experiment_name', stableRand()) % 100 < 50
Rollout to winner: true
if A won, false
if B won
You'll need to add which test variant the user is in to any success analytics in order to measure your results.
Adding real-time conditional targeting is a powerful addition to typical server driven feature flags.
Some examples of benefits over typical randomized feature flag rollouts:
A common tactic for testing social apps it to rollout to a specific geography so all users who interact see the same UI, eg locale_country_code == 'CA'
Target devices that are better tested on the new feature to start getting feedback sooner (iPhones to start, iPads later, only the latest iOS version)
Target only users who have been using the app a while, as changing the UI on new users provides less valuable data and increases churn
Targeted rollbacks: disable the feature if bugs are found, but only on the impacted devices, and without canceling the entire rollout. For example you can rollback: bugs with dark mode, bugs in specific locales, bugs when offline, bugs on specific devices, and much more.
You can take advantage of both systems together if you want to keep your existing system, while also using Critical Moments Targeting with a simple &&
evaluation.
You can update your feature flag state anytime from the cloud. This can include updating their state (true/false), updating their , , or changing their .
Here's a sample config file format with two feature flags (see for full details):
The remote update process is detailed .
Our can be use to rollout to a small set of users, and grow it over time.
This is just an example. You can modify the condition using our powerful to create your own targeting logic.
We support which can be helpful for cases you didn't predict before releasing to the app store.
One conditional feature flag is included in our free plan, and small business qualify for free unlimited conditional feature flags. See our for more details.
You might already be invested in another tool for feature flag tool. It's likely that tool doesn't support powerful or like Critical Moments does.