Use forced bucketing
How to use forced bucketing to put a user into a certain variation in Optimizely Feature Experimentation.
Forced bucketing lets you programmatically put a user into a variation from within your code.
The Forced Decision methods let you
- Set the forced decision.
- Get the forced decision.
- Remove the forced decision.
- Remove all forced decisions.
To force a user into a variation, call the SDK Forced Decision methods to test and debug various flows of your client applications by forcing users into a specific variation.
- Android
- C#
- Flutter
- Go
- Java
- JavaScript (Browser)
- JavaScript (Node)
- PHP
- Python
- React
- React Native
- Ruby
- Swift
Unlike allowlisting, forced bucketing takes place immediately (meaning, without waiting for a datafile update) and has no limit on users that can be forced.
Example usage
See the following code examples for implementation information.
Client-side SDK examples
// Create the OptimizelyUserContext, passing in the UserId and Attributes
val user = optimizelyClient.createUserContext("user-id")
val flagContext = OptimizelyDecisionContext("flag-1", null)
val flagAndABTestContext = OptimizelyDecisionContext("flag-1", "exp-1")
val flagAndDeliveryRuleContext = OptimizelyDecisionContext("flag-1", "delivery-1")
val variationAForcedDecision = OptimizelyForcedDecision("variation-a")
val variationBForcedDecision = OptimizelyForcedDecision("variation-b")
val variationOnForcedDecision = OptimizelyForcedDecision("on")
// set a forced decision for a flag
var success = user!!.setForcedDecision(flagContext, variationAForcedDecision)
var decision = user.decide("flag-1")
// set a forced decision for an ab-test rule
success = user.setForcedDecision(flagAndABTestContext, variationBForcedDecision)
decision = user.decide("flag-1")
// set a forced variation for a delivery rule
success = user.setForcedDecision(flagAndDeliveryRuleContext, variationOnForcedDecision)
decision = user.decide("flag-1")
// get forced variations
val forcedDecision = user.getForcedDecision(flagContext)
println("[ForcedDecision] variationKey = " + forcedDecision!!.variationKey)
// remove forced variations
success = user.removeForcedDecision(flagAndABTestContext)
success = user.removeAllForcedDecisions()
/* Create the OptimizelyUserContext, passing in the UserId and Attributes */
OptimizelyUserContext user = optimizelyClient.createUserContext("user-id");
OptimizelyDecisionContext flagContext = new OptimizelyDecisionContext("flag-1", null);
OptimizelyDecisionContext flagAndABTestContext = new OptimizelyDecisionContext("flag-1", "exp-1");
OptimizelyDecisionContext flagAndDeliveryRuleContext = new OptimizelyDecisionContext("flag-1", "delivery-1");
OptimizelyForcedDecision variationAForcedDecision = new OptimizelyForcedDecision("variation-a");
OptimizelyForcedDecision variationBForcedDecision = new OptimizelyForcedDecision("variation-b");
OptimizelyForcedDecision variationOnForcedDecision = new OptimizelyForcedDecision("on");
// set a forced decision for a flag
Boolean success = user.setForcedDecision(flagContext, variationAForcedDecision);
OptimizelyDecision decision = user.decide("flag-1");
// set a forced decision for an ab-test rule
success = user.setForcedDecision(flagAndABTestContext, variationBForcedDecision);
decision = user.decide("flag-1");
// set a forced variation for a delivery rule
success = user.setForcedDecision(flagAndDeliveryRuleContext, variationOnForcedDecision);
decision = user.decide("flag-1");
// get forced variations
OptimizelyForcedDecision forcedDecision = user.getForcedDecision(flagContext);
System.out.println("[ForcedDecision] variationKey = " + forcedDecision.getVariationKey());
// remove forced variations
success = user.removeForcedDecision(flagAndABTestContext);
success = user.removeAllForcedDecisions();
/* Create the OptimizelyUserContext, passing in the UserId and Attributes */
var user = await optimizelyClient.createUserContext(userId: "user-id");
var flagContext = OptimizelyDecisionContext("flag-1");
var flagAndABTestContext = OptimizelyDecisionContext("flag-1", "exp-1");
var flagAndDeliveryRuleContext = OptimizelyDecisionContext("flag-1", "delivery-1");
var variationAForcedDecision = OptimizelyForcedDecision("variation-a");
var variationBForcedDecision = OptimizelyForcedDecision("variation-b");
var variationOnForcedDecision = OptimizelyForcedDecision("on");
// set a forced decision for a flag
var success = await user!.setForcedDecision(flagContext, variationAForcedDecision);
var decision = await user.decide("flag-1");
// set a forced decision for an ab-test rule
success = await user.setForcedDecision(flagAndABTestContext, variationBForcedDecision);
decision = await user.decide("flag-1");
// set a forced variation for a delivery rule
success = await user.setForcedDecision(flagAndDeliveryRuleContext, variationOnForcedDecision);
decision = await user.decide("flag-1");
// get forced variations
var forcedDecision = await user.getForcedDecision(flagContext);
print("[ForcedDecision] variationKey = ${forcedDecision.variationKey}");
// remove forced variations
success = await user.removeForcedDecision(flagAndABTestContext);
success = await user.removeAllForcedDecisions();
import { createInstance } from '@optimizely/optimizely-sdk';
const optimizely = createInstance({
sdkKey: '<YOUR_SDK_KEY>'// Provide the sdkKey of your desired environment here
});
if (optimizely) {
optimizely.onReady().then(({ success, reason }) => {
if (!success) {
throw new Error(reason);
}
const attributes = { logged_in: true };
const user = optimizely.createUserContext('user123', attributes);
if (!user) {
throw new Error('failed to create user context');
}
let result, decision, forcedDecision;
// set a forced decision for a flag
result = user.setForcedDecision({flagKey: 'flag-1'}, {variationKey: 'off'});
decision = user.decide('flag-1');
// set a forced decision for an ab-test rule
result = user.setForcedDecision({flagKey: 'flag-2', ruleKey: 'ab-test-1'}, {variationKey: 'variation-b'});
decision = user.decide('flag-2');
// set a forced variation for a delivery rule
result = user.setForcedDecision({flagKey: 'flag-3', ruleKey: 'delivery-1'}, {variationKey: 'on'});
decision = user.decide('flag-3');
// get forced variations
forcedDecision = user.getForcedDecision({flagKey: 'flag-2'});
// remove forced variations
result = user.removeForcedDecision({flagKey: 'flag-2', ruleKey: 'ab-test-1'});
user.removeAllForcedDecisions();
user.decideAll();
}).catch((err) => {
console.log(err);
// handle error
});
} else {
// handle instantiation error
}
const { createInstance } = require('@optimizely/optimizely-sdk');
const optimizely = createInstance({
sdkKey: '<YOUR_SDK_KEY>'// Provide the sdkKey of your desired environment here
});
if (optimizely) {
optimizely.onReady().then(({ success, reason }) => {
if (!success) {
throw new Error(reason);
}
const attributes = { logged_in: true };
const user = optimizely.createUserContext('user123', attributes);
if (!user) {
throw new Error('failed to create user context');
}
let result, decision, forcedDecision;
// set a forced decision for a flag
result = user.setForcedDecision({flagKey: 'flag-1'}, {variationKey: 'off'});
decision = user.decide('flag-1');
// set a forced decision for an ab-test rule
result = user.setForcedDecision({flagKey: 'flag-2', ruleKey: 'ab-test-1'}, {variationKey: 'variation-b'});
decision = user.decide('flag-2');
// set a forced variation for a delivery rule
result = user.setForcedDecision({flagKey: 'flag-3', ruleKey: 'delivery-1'}, {variationKey: 'on'});
decision = user.decide('flag-3');
// get forced variations
forcedDecision = user.getForcedDecision({flagKey: 'flag-2'});
// remove forced variations
result = user.removeForcedDecision({flagKey: 'flag-2', ruleKey: 'ab-test-1'});
user.removeAllForcedDecisions();
user.decideAll();
}).catch((err) => {
console.log(err);
// handle error
});
} else {
// handle instantiation error
}
import React from "react";
import {
createInstance,
OptimizelyProvider,
useDecision,
withOptimizely,
} from "@optimizely/react-sdk";
const optimizely = createInstance({
sdkKey: "<YOUR_SDK_KEY_HERE>",
});
optimizely.onUserUpdate(() => {
// Wait for the user to be available before using forced decision methods.
optimizely.setForcedDecision({ flagKey: "product_sort" }, { variationKey: "treatment" });
});
const PurchaseButton = withOptimizely((props: any) => {
const handleClick = () => {
const { optimizely } = props;
optimizely.track("purchased");
};
return <div><button onClick={handleClick}>Purchase</button></div>;
});
const RemoveForcedDecision = withOptimizely((props: any) => {
const handleClick = () => {
const { optimizely } = props;
optimizely.removeForcedDecision({ flagKey: 'product_sort' });
};
return <div><button onClick={handleClick}>Remove Forced Decision</button></div>;
});
const RemoveAllForcedDecisions = withOptimizely((props: any) => {
const handleClick = () => {
const { optimizely } = props;
optimizely.removeAllForcedDecisions();
};
return <div><button onClick={handleClick}>Remove All Forced Decisions</button></div>;
});
function ProductSort() {
const [decision] = useDecision("product_sort", {
autoUpdate: true
});
const variationKey = decision.variationKey;
const isEnabled = decision.enabled;
const sortMethod = decision.variables["sort_method"];
return (
<div>
{/* If variation is null, display error */}
{variationKey === null && <div className="error">{decision.reasons}</div>}
{/* If feature is enabled, do something with the Sort Method variable */}
{isEnabled && <div>The Sort method is {sortMethod}</div>}
{/* Show relevant component based on the variation key */}
{variationKey === "control" && <div>Control Component</div>}
{variationKey === "treatment" && <div>Treatment Component</div>}
{/* Show Purchase Button to track Purchase event */}
<PurchaseButton />
<RemoveForcedDecision />
<RemoveAllForcedDecisions />
</div>
);
}
function App() {
return (
<OptimizelyProvider
optimizely={optimizely}
user={{
id: "user123",
}}
>
<ProductSort />
</OptimizelyProvider>
);
}
export default App;
import React from "react";
import {
createInstance,
OptimizelyProvider,
useDecision,
withOptimizely,
} from "@optimizely/react-sdk";
const optimizely = createInstance({
sdkKey: "<YOUR_SDK_KEY_HERE>",
});
optimizely.onUserUpdate(() => {
// Wait for the user to be available before using forced decision methods.
optimizely.setForcedDecision({ flagKey: "product_sort" }, { variationKey: "treatment" });
});
const PurchaseButton = withOptimizely((props: any) => {
const handleClick = () => {
const { optimizely } = props;
optimizely.track("purchased");
};
return <div><button onClick={handleClick}>Purchase</button></div>;
});
const RemoveForcedDecision = withOptimizely((props: any) => {
const handleClick = () => {
const { optimizely } = props;
optimizely.removeForcedDecision({ flagKey: 'product_sort' });
};
return <div><button onClick={handleClick}>Remove Forced Decision</button></div>;
});
const RemoveAllForcedDecisions = withOptimizely((props: any) => {
const handleClick = () => {
const { optimizely } = props;
optimizely.removeAllForcedDecisions();
};
return <div><button onClick={handleClick}>Remove All Forced Decisions</button></div>;
});
function ProductSort() {
const [decision] = useDecision("product_sort", {
autoUpdate: true
});
const variationKey = decision.variationKey;
const isEnabled = decision.enabled;
const sortMethod = decision.variables["sort_method"];
return (
<div>
{/* If variation is null, display error */}
{variationKey === null && <div className="error">{decision.reasons}</div>}
{/* If feature is enabled, do something with the Sort Method variable */}
{isEnabled && <div>The Sort method is {sortMethod}</div>}
{/* Show relevant component based on the variation key */}
{variationKey === "control" && <div>Control Component</div>}
{variationKey === "treatment" && <div>Treatment Component</div>}
{/* Show Purchase Button to track Purchase event */}
<PurchaseButton />
<RemoveForcedDecision />
<RemoveAllForcedDecisions />
</div>
);
}
function App() {
return (
<OptimizelyProvider
optimizely={optimizely}
user={{
id: "user123",
}}
>
<ProductSort />
</OptimizelyProvider>
);
}
export default App;
let optimizely = OptimizelyClient(sdkKey: “sdk-key”)
optimizely.start(datafile: datafile)
let user = optimizely.createUserContext(userId: “test-user”, attributes: attributes)
let flagContext = OptimizelyDecisionContext(flagKey: "flag-1")
let flagAndABTestContext = OptimizelyDecisionContext(flagKey: "flag-1", ruleKey: "ab-test-1")
let flagAndDeliveryRuleContext = OptimizelyDecisionContext(flagKey: "flag-1", ruleKey: "delivery-1")
let variationAForcedDecision = OptimizelyForcedDecision(variationKey: "variation-a")
let variationBForcedDecision = OptimizelyForcedDecision(variationKey: "variation-b")
let variationOnForcedDecision = OptimizelyForcedDecision(variationKey: "on")
// set a forced decision for a flag
var success = user.setForcedDecision(context: flagContext, decision: variationAForcedDecision)
decision = user.decide(key: "flag-1")
// set a forced decision for an ab-test rule
success = user.setForcedDecision(context: flagAndABTestContext, decision: variationBForcedDecision)
decision = user.decide(key: "flag-1")
// set a forced variation for a delivery rule
success = user.setForcedDecision(context: flagAndDeliveryRuleContext, decision: variationOnForcedDecision)
decision = user.decide(key: "flag-1")
// get forced variations
let forcedDecision = user.getForcedDecision(context: flagContext)
print("[ForcedDecision] variationKey = \(forcedDecision!.variationKey)")
// remove forced variations
success = user.removeForcedDecision(context: flagAndABTestContext)
success = user.removeAllForcedDecisions()
Server-side SDK examples
var Optimizely = OptimizelyFactory.NewDefaultInstance("<your sdk key>");
var attributes = new UserAttributes();
var user = Optimizely.CreateUserContext(RandomUserId(), attributes);
var flagContext = new OptimizelyDecisionContext("flag-1", null);
var flagAndABTestContext = new OptimizelyDecisionContext("flag-1", "ab-test-1");
var flagAndDeliveryRuleContext = new OptimizelyDecisionContext("flag-1", "delivery-1");
var variationAForcedDecision = new OptimizelyForcedDecision("variation-a");
var variationBForcedDecision = new OptimizelyForcedDecision("variation-b");
var variationOnForcedDecision = new OptimizelyForcedDecision("on");
// set a forced decision for a flag
var success = user.SetForcedDecision(flagContext, variationAForcedDecision);
var decision = user.Decide("flag-1");
// set a forced decision for an ab-test rule
success = user.SetForcedDecision(flagAndABTestContext, variationBForcedDecision);
decision = user.Decide("flag-1");
// set a forced variation for a delivery rule
success = user.SetForcedDecision(flagAndDeliveryRuleContext, variationOnForcedDecision);
decision = user.Decide("flag-1");
// get forced variations
var forcedDecision = user.GetForcedDecision(flagContext);
Console.WriteLine(string.Format("ForcedDecision variationKey = {0}", forcedDecision.VariationKey));
// remove forced variations
success = user.RemoveForcedDecision(flagAndABTestContext);
success = user.RemoveAllForcedDecisions();
factory := &client.OptimizelyFactory{SDKKey: "sdk-key"}
if optimizely, err := factory.StaticClient(); err == nil {
user := optimizely.CreateUserContext("test-user", map[string]interface{}{})
flagContext := decision.OptimizelyDecisionContext{FlagKey: "flag-1"}
flagAndABTestContext := decision.OptimizelyDecisionContext{FlagKey: "flag-1", RuleKey: "ab-test-1"}
flagAndDeliveryRuleContext := decision.OptimizelyDecisionContext{FlagKey: "flag-1", RuleKey: "delivery-1"}
variationAForcedDecision := decision.OptimizelyForcedDecision{VariationKey: "variation-a"}
variationBForcedDecision := decision.OptimizelyForcedDecision{VariationKey: "variation-b"}
variationOnForcedDecision := decision.OptimizelyForcedDecision{VariationKey: "on"}
// set a forced decision for a flag
success := user.SetForcedDecision(flagContext, variationAForcedDecision)
decision := user.Decide("flag-1", nil)
// set a forced decision for an ab-test rule
success = user.SetForcedDecision(flagAndABTestContext, variationBForcedDecision)
decision = user.Decide("flag-1", nil)
// set a forced variation for a delivery rule
success = user.SetForcedDecision(flagAndDeliveryRuleContext, variationOnForcedDecision)
decision = user.Decide("flag-1", nil)
// get forced variations
if forcedDecision, err := user.GetForcedDecision(flagContext); err == nil {
fmt.Println("[ForcedDecision] variationKey = " + forcedDecision.VariationKey)
}
// remove forced variations
success = user.RemoveForcedDecision(flagAndABTestContext)
success = user.RemoveAllForcedDecisions()
}
/* Create the Optimizely instance and provide the sdk-key */
Optimizely optimizely = OptimizelyFactory.newDefaultInstance("sdk-key");
/* Create the OptimizelyUserContext, passing in the UserId and Attributes */
OptimizelyUserContext user = optimizely.createUserContext("user-id", Collections.emptyMap());
OptimizelyDecisionContext flagContext = new OptimizelyDecisionContext("flag-1");
OptimizelyDecisionContext flagAndABTestContext = new OptimizelyDecisionContext("flag-1", "ab-test-1");
OptimizelyDecisionContext flagAndDeliveryRuleContext = new OptimizelyDecisionContext("flag-1", "delivery-1");
OptimizelyForcedDecision variationAForcedDecision = new OptimizelyForcedDecision("variation-a");
OptimizelyForcedDecision variationBForcedDecision = new OptimizelyForcedDecision("variation-b");
OptimizelyForcedDecision variationOnForcedDecision = new OptimizelyForcedDecision("on");
// set a forced decision for a flag
Boolean success = user.setForcedDecision(flagContext, variationAForcedDecision);
OptimizelyDecision decision = user.decide("flag-1");
// set a forced decision for an ab-test rule
success = user.setForcedDecision(flagAndABTestContext, variationBForcedDecision);
decision = user.decide("flag-1");
// set a forced variation for a delivery rule
success = user.setForcedDecision(flagAndDeliveryRuleContext, variationOnForcedDecision);
decision = user.decide("flag-1");
// get forced variations
OptimizelyForcedDecision forcedDecision = user.getForcedDecision(flagContext);
System.out.println("[ForcedDecision] variationKey = " + forcedDecision.getVariationKey());
// remove forced variations
success = user.removeForcedDecision(flagAndABTestContext);
success = user.removeAllForcedDecisions();
$optimizelyClient = OptimizelyFactory::createDefaultInstance($sdkKey);
$user = $optimizelyClient->createUserContext('test_user', $attributes);
$flagContext = new OptimizelyDecisionContext('flag-1', null);
$flagAndABTestContext = new OptimizelyDecisionContext('flag-1', 'ab-test-1');
$flagAndDeliveryRuleContext = new OptimizelyDecisionContext('flag-1', 'delivery-1');
$variationAForcedDecision = new OptimizelyForcedDecision('variation-a');
$variationBForcedDecision = new OptimizelyForcedDecision('variation-b');
$variationOnForcedDecision = new OptimizelyForcedDecision('on');
# set a forced decision for a flag
$success = $user->setForcedDecision($flagContext, $variationAForcedDecision);
$decision = $user->decide('flag-1');
# set a forced decision for an ab-test rule
$success = $user->setForcedDecision($flagAndABTestContext, $variationBForcedDecision);
$decision = $user->decide('flag-1');
# set a forced variation for a delivery rule
$success = $user->setForcedDecision($flagAndDeliveryRuleContext, $variationOnForcedDecision);
$decision = $user->decide('flag-1');
# get forced variations
$forcedDecision = $user->getForcedDecision($flagContext);
echo "[ForcedDecision] variationKey = {$forcedDecision}";
# remove forced variations
$success = $user->removeForcedDecision($flagAndABTestContext);
$success = $user->removeAllForcedDecisions();
from optimizely import optimizely, optimizely_user_context
optimizely_client = optimizely.Optimizely(sdk_key="<YOUR_SDK_KEY>")
user = optimizely_client.create_user_context("test_user", attributes)
flag_context = optimizely_user_context.OptimizelyUserContext.OptimizelyDecisionContext("flag-1",None)
flag_and_ab_test_context = optimizely_user_context.OptimizelyUserContext.OptimizelyDecisionContext("flag-1","ab-test-1")
flag_and_delivery_rule_context = optimizely_user_context.OptimizelyUserContext.OptimizelyDecisionContext("flag-1","delivery-1")
variation_a_forced_decision = optimizely_user_context.OptimizelyUserContext.OptimizelyForcedDecision("variation-a")
variation_b_forced_decision = optimizely_user_context.OptimizelyUserContext.OptimizelyForcedDecision("variation-b")
variation_on_forced_decision = optimizely_user_context.OptimizelyUserContext.OptimizelyForcedDecision("on")
# set a forced decision for a flag
success = user.set_forced_decision(flag_context, variation_a_forced_decision)
decision = user.decide("flag-1")
# set a forced decision for an ab-test rule
success = user.set_forced_decision(flag_and_ab_test_context, variation_b_forced_decision)
decision = user.decide("flag-1")
# set a forced variation for a delivery rule
success = user.set_forced_decision(flag_and_delivery_rule_context, variation_on_forced_decision)
decision = user.decide("flag-1")
# get forced variations
forced_decision = user.get_forced_decision(flag_context)
print(f"[ForcedDecision] variation_key = {forced_decision}")
# remove forced variations
success = user.remove_forced_decision(flag_and_ab_test_context)
success = user.remove_all_forced_decision()
require 'optimizely'
require 'optimizely/optimizely_factory'
optimizely = Optimizely::OptimizelyFactory.default_instance('sdk_key')
user = optimizely.create_user_context('test_user', attributes)
flag_context = Optimizely::OptimizelyUserContext::OptimizelyDecisionContext.new('flag-1', nil)
flag_and_ab_test_context = Optimizely::OptimizelyUserContext::OptimizelyDecisionContext.new('flag-1','ab-test-1')
flag_and_delivery_rule_context = Optimizely::OptimizelyUserContext::OptimizelyDecisionContext.new('flag-1','delivery-1')
variation_a_forced_decision = Optimizely::OptimizelyUserContext::OptimizelyForcedDecision.new('variation-a')
variation_b_forced_decision = Optimizely::OptimizelyUserContext::OptimizelyForcedDecision.new('variation-b')
variation_on_forced_decision = Optimizely::OptimizelyUserContext::OptimizelyForcedDecision.new('on')
# set a forced decision for a flag
success = user.set_forced_decision(flag_context, variation_a_forced_decision)
decision = user.decide('flag-1')
# set a forced decision for an ab-test rule
success = user.set_forced_decision(flag_and_ab_test_context, variation_b_forced_decision)
decision = user.decide('flag-1')
# set a forced variation for a delivery rule
success = user.set_forced_decision(flag_and_delivery_rule_context, variation_on_forced_decision)
decision = user.decide('flag-1')
# get forced variations
forced_decision = user.get_forced_decision(flag_context)
puts "[ForcedDecision] variation_key = #{forced_decision}"
# remove forced variations
success = user.remove_forced_decision(flag_and_ab_test_context)
success = user.remove_all_forced_decisions
Updated 2 months ago