FeatureSignals

Mutual Exclusion

Mutual exclusion prevents two or more feature flags from being enabled for the same user at the same time. It's the guardrail that keeps concurrent experiments from interfering with each other.

What Are Mutual Exclusion Groups?

A mutual exclusion group is a named set of flags where only one can evaluate to a non-default value for any given user. Flags in the group are evaluated in priority order (by position in the group). The first flag that matches its targeting rules and is enabled wins — all subsequent flags in the group return their default values.

When to Use Mutual Exclusion

  • Overlapping experiments. If two A/B tests modify the same UI surface or backend path, running them simultaneously can produce misleading results. Mutual exclusion ensures each user only participates in one experiment.
  • Conflicting feature variants.When you're testing two mutually exclusive implementations of the same feature, you need to guarantee a user only sees one.
  • Resource-constrained rollouts.If you're gradually rolling out multiple features that share a scarce resource (database capacity, API rate limits), mutual exclusion prevents a user from being in multiple rollout cohorts simultaneously.

Important

Mutual exclusion only applies when flags are in the same group and have the same group name. Flags in different groups (or not in any group) are evaluated independently.

How It Works

Mutual exclusion is checked early in the evaluation order — after the flag existence check and environment enabled check, but before targeting rules. This ensures that the exclusion group logic runs efficiently and doesn't waste time evaluating targeting rules for flags that will be excluded.

Here's the evaluation flow with mutual exclusion:

text
1. Flag exists?                 No: NOT_FOUND
2. Flag environment enabled?     No: DISABLED
3. Mutual exclusion group?       Yes: check if another flag in the same group
                                   has already won for this user
                                    If another flag won: MUTUALLY_EXCLUDED
                                    If no other flag won: continue
4. Prerequisites met?            No: PREREQUISITE_FAILED
5. Targeting rules match?        Yes: TARGETED (rule value)
6. Percentage rollout?           In bucket: ROLLOUT / Out: FALLTHROUGH
7. A/B variant assignment?       Yes: VARIANT
8. None of the above             FALLTHROUGH

Example: Two Conflicting Experiments

Imagine you're running two experiments simultaneously:

FlagExperimentGroup
checkout-redesignComplete UI overhaul of the checkout flowcheckout-experiments
checkout-one-clickOne-click purchase for returning customerscheckout-experiments

Both flags are in the checkout-experiments mutual exclusion group. When a user starts checkout:

  1. Evaluate checkout-redesign — If the user is targeted (e.g., 50% rollout), they get the redesigned checkout. checkout-one-click is now excluded for this user.
  2. Evaluate checkout-one-click — The engine sees that checkout-redesign already won in the checkout-experiments group. It returns MUTUALLY_EXCLUDED and the default value (OFF).

This guarantees each user sees exactly one checkout experiment at a time, preserving the integrity of both tests.

Configuring Mutual Exclusion

Set the mutual_exclusion_group property when creating or updating a flag. All flags with the same group name are mutually exclusive:

bash
curl -X PATCH https://api.featuresignals.com/v1/projects/$PROJECT_ID/flags/$FLAG_ID \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "mutual_exclusion_group": "checkout-experiments"
  }'

Best Practices

  • Name groups descriptively. checkout-experiments is clearer than group-1.
  • Keep groups focused. Only add flags that genuinely conflict. Overly broad groups can unintentionally suppress valid experiments.
  • Be deliberate about order. Flags are evaluated in priority order within the group. If one experiment is higher priority, put it first.
  • Document the group. Add a comment or description explaining why the flags are mutually exclusive. Future you (and your teammates) will thank you.
  • Remove flags from the group after the experiment ends.Archiving a flag doesn't automatically remove it from the mutual exclusion group.

Next Steps