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:
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 → FALLTHROUGHExample: Two Conflicting Experiments
Imagine you're running two experiments simultaneously:
| Flag | Experiment | Group |
|---|---|---|
checkout-redesign | Complete UI overhaul of the checkout flow | checkout-experiments |
checkout-one-click | One-click purchase for returning customers | checkout-experiments |
Both flags are in the checkout-experiments mutual exclusion group. When a user starts checkout:
- Evaluate
checkout-redesign— If the user is targeted (e.g., 50% rollout), they get the redesigned checkout.checkout-one-clickis now excluded for this user. - Evaluate
checkout-one-click— The engine sees thatcheckout-redesignalready won in thecheckout-experimentsgroup. It returnsMUTUALLY_EXCLUDEDand 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:
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-experimentsis clearer thangroup-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.