Feature Flags Guide

Best practices for feature flags

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 realtime conditional targeting: 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

  • Completely private trustless deployments: you don't need to trust our server infrastrcture

Install Critical Moments

If you haven't already, follow our quick start guide to integrate Critical Moments into your app.

Client API

Use the checkNamedCondition API in your app to check feature flags values in code.

CriticalMoments.sharedInstance().checkNamedCondition("userNotDistracted") { result, error in
    if let error {
        print("Issue evaluating conditional:", error)
    } else if result {
        // Perform action

Remote Updates

You can update your feature flag state anytime from the cloud. This can include updating their state (true/false), updating their rollout percentage, rolling back, or changing their conditional logic.

Here's a sample config file format with two feature flags (see docs for full details):

"conditions": {
  "namedConditions": {
    "feature_one": "true",
    "experiment_two": "false"

The remote update process is detailed here.

Progressive Rollouts

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.

Implementing Progressive Rollouts

Our random number generating functions can be use to rollout to a small set of users, and grow it over time.

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

This is just an example. You can modify the condition using our powerful conditions engine to create your own targeting logic.

The stableRand and randForKey functions can be used in unlimited feature flags, even on our free plan!

Understanding the Conditionals

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.

Basic Rollbacks

Disabling a feature flag is as easy as pushing a conditional string that will evaluate to false, such as false.

Targeted Rollbacks

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')))

  • We support over 100 other options which can be helpful for cases you didn't predict before releasing to the app store.

AB Test Variant Selection

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.

Conditional Targeting

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.

One conditional feature flag is included in our free plan, and small business qualify for free unlimited conditional feature flags. See our pricing for more details.

Combining with Existing Feature Flag Tools

You might already be invested in another tool for feature flag tool. It's likely that tool doesn't support powerful conditional targeting or targeted rollbacks like Critical Moments does.

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.

Last updated