Assign variations with bucketing ids
Use a bucketing ID to decouple user bucketing from user identification.
By default, Optimizely assigns users to variations (in other words, Optimizely buckets users) based on submitted user IDs. You can change this behavior by including a bucketing ID.
With a bucketing ID, you decouple user bucketing from user identification. Users with the same bucketing ID are put into the same bucket and exposed to the same variation. The bucketing ID serves as the seed of the hash value used to assign the user to a variation. Users with the same bucketing ID share the same hash value, exposing them to the same variation. For information, see How bucketing works.
Bucketing IDs are implemented as a reserved attribute that you can use when activating an experiment or evaluating a feature flag.
Using a bucketing ID does not affect the user ID. Event data submissions continue to include user IDs. Except for assigning users to specific variations, flags that rely on user IDs behave the same even if there is a separate bucketing ID. If you do not pass a bucketing ID to the attributes
parameter, users are bucketed by user IDs by default.
Note
Bucketing IDs:
- are not persisted.
- are only supported for A/B tests and multi-armed bandit optimizations.
Use case
Maintaining consistent user experiences across sessions is crucial. Bucketing IDs offer a solution by providing a consistent identifier for user bucketing.
Shared device example
For example, you run experiments on a shared device like an Apple TV. Multiple users in a household can use the same device.
You want to ensure that you assign experiment variations based on the device instead of the individual user. If Optimizely bucketed according to individual users, then users on the same device may get different experiences, which may threaten the experiment's validity.
By using a unique device identifier as the bucketing ID, you can ensure that all users on the same shared device experience the same experiment variation. You can still track events like conversions for each individual user by creating user contexts using unique user identifiers.
See your SDK's guide on creating a user context:
- Android
- C#
- Flutter
- Go
- Java
- JavaScript (Browser)
- JavaScript (Node)
- PHP
- Python
- React
- React Native
- Ruby
- Swift
Example implementation
The following examples show how to include a bucketing ID. Send the $opt_bucketing_id
attribute in the attributes
parameter of the optimizelyUserContext
.
Client-side SDKs
import java.util.UUID;
import com.optimizely.ab.android.sdk.OptimizelyClient;
String experiementKey = "my_experiment";
// for simplicity's sake, we are just using a generated user id
String userId = UUID.randomUUID().toString();
// Option 1 – Create a user, then set the attributes
OptimizelyUserContext user;
user = optimizelyClient.createUserContext(userId);
user.setAttribute("ad_source", "my_campaign");
user.setAttribute("browser", "chrome");
user.setAttribute("$opt_bucketing_id", "bucketingId123");
// Option 2 – Pass attributes when creating the user
Map<String,String> attributes = new HashMap<String,String>();
attributes.put("ad_source", "my_campaign");
attributes.put("browser", "chrome");
// bucketing id can be passed in alone or with other attributes
attributes.put("$opt_bucketing_id", "bucketingId123");
user = optimizelyClient.createUserContext(userId, attributes);
import java.util.UUID
import com.optimizely.ab.android.sdk.OptimizelyClient
val experimentKey = "my_experiment"
// for simplicity's sake, we are just using a generated user id
val userId = UUID.randomUUID().toString()
// Option 1 – Create a user, then set attributes
var user: OptimizelyUserContext?
user = optimizelyClient.createUserContext(userId)
user.setAttribute("ad_source", "my_campaign")
user.setAttribute("browser", "chrome")
user.setAttribute("$opt_bucketing_id", "bucketingId123")
// Option 2 – Pass attributes when creating the user
val attributes: MutableMap<String, Any> = HashMap()
attributes["ad_source"] = "my_campaign"
attributes["browser"] = "chrome"
attributes["$opt_bucketing_id"] = "bucketingId123"
user = optimizelyClient.createUserContext(userId, attributes)
import 'package:uuid/uuid.dart';
void main() {
var experimentKey = "my_experiment";
// for simplicity's sake, we are just using a generated user id
var userId = Uuid().v4();
}
// Option 1 – Create a user, then set attributes
var user = await flutterSDK.createUserContext(userId);
var attributes = <String, dynamic>{};
attributes["ad_source"] = "my_campaign";
attributes["app_version"] = "1.3.2";
attributes["$opt_bucketing_id"] = "bucketingId123";
user!.setAttributes(attributes);
// Option 2 – Pass attributes when creating the user
var attributes = <String, dynamic>{};
attributes["ad_source"] = "my_campaign";
attributes["app_version"] = "1.3.2";
attributes["$opt_bucketing_id"] = "bucketingId123";
var optimizelyUserContext = await optimizelyClient.createUserContext(userId: userId, attributes: attributes);
const experimentKey = 'my_experiment';
// For simplicity's sake, we are just using a hardcoded user id
const userId = 'user123';
// Option 1 – Create a user, then set attributes
const user = optimizely.createUserContext(userId);
user.setAttribute('is_logged_in', false);
user.setAttribute('app_version', '1.3.2');
user.setAttribute('$opt_bucketing_id': 'bucketingId123');
// Option 2 – Pass attributes when creating the user
const attributes = {
'ad_source': 'my_campaign',
'device': 'iphone',
'$opt_bucketing_id': 'bucketingId123'
}
const user = optimizely.createUserContext(userId, attributes);
import { createInstance, OptimizelyProvider } from '@optimizely/react-sdk'
const optimizely = createInstance({
sdkKey: '<YOUR_SDK_KEY>'
})
export default function App() {
return (
<OptimizelyProvider
optimizely={optimizely}
user={{
id: 'user123',
attributes: { $opt_bucketing_id: 'bucketingId123' }
}}
>
// Components
</OptimizelyProvider>
)
}
import { createInstance, OptimizelyProvider } from '@optimizely/react-sdk'
const optimizely = createInstance({
sdkKey: '<YOUR_SDK_KEY>'
})
export default function App() {
return (
<OptimizelyProvider
optimizely={optimizely}
user={{
id: 'user123',
attributes: { $opt_bucketing_id: 'bucketingId123' }
}}
>
// Components
</OptimizelyProvider>
)
}
let optimizely = OptimizelyClient(sdkKey: "sdk-key")
let experimentKey = "myExperiment"
// For simplicity's sake, we are just using a hardcoded user id
let userId = "user123"
optimizely.start {
// Option 1 – Create a user, then set attributes
let user = optimizely.createUserContext(userId: userId)
user.setAttribute(key: "is_logged_in", value: false)
user.setAttribute(key: "app_version", value: "1.3.2")
user.setAttribute(key: "$opt_bucketing_id", value: "bucketingId123")
// Option 2 – Pass attributes when creating the user
let attributes: [String: Any] = [
"device": "iPhone",
"lifetime": 24738388,
"is_logged_in": true,
"app_version": "4.3.0-beta",
"$opt_bucketing_id": "bucketingId123",
]
let user = optimizely.createUserContext(userId: userId, attributes: attributes)
}
Server-side SDKs
using OptimizelySDK;
using OptimizelySDK.Entity;
var optimizelyClient = new Optimizely(datafile);
var experimentKey = "my_experiment";
// for simplicity's sake, we are just using a hardcoded user id
var userId = "user123";
// Option 1 – Create a user, then set attributes
var user = optimizely.CreateUserContext(userId);
user.SetAttribute("AD_SOURCE", "my_campaign");
user.SetAttribute("BROWSER", "chrome");
user.SetAttribute("$opt_bucketing_id", "bucketingId123");
// option 2: pass attributes when creating the user
var attributes = new UserAttributes
{
{ "AD_SOURCE", "my_campaign" },
{ "BROWSER", "chrome" },
{ "$opt_bucketing_id", "bucketingId123" }
};
var user = optimizely.CreateUserContext(userId, attributes);
import "github.com/optimizely/go-sdk/pkg/client" // for v2: "github.com/optimizely/go-sdk/v2/pkg/client"
experimentKey := "my_experiment"
// for simplicity's sake, we are just using a hardcoded user id
userId := "user123"
// Option 1: Create a user, then set attributes
user := client.CreateUserContext(userId, nil)
user.SetAttribute("ad_source", "my_campaign")
user.SetAttribute("app_version", "1.3.2")
user.SetAttribute("$opt_bucketing_id", "bucketingId123")
// Option 2: Pass attributes when creating the user
attributes := map[string]interface{}{
"ad_source": "my_campaign",
"app_version": "1.3.2",
"is_logged_in": true,
"$opt_bucketing_id": "bucketingId123",
}
user = client.CreateUserContext(userId, attributes)
import java.util.UUID;
import com.optimizely.ab.Optimizely;
import com.optimizely.ab.config.Variation;
String experiementKey = "my_experiment";
// For simplicity's sake, We are just using a generated user id
String userId = UUID.randomUUID().toString();
// Option 1 – Create a user, then set the attributes
OptimizelyUserContext user = optimizelyClient.createUserContext(userId);
user.setAttribute("ad_source", "my_campaign");
user.setAttribute("browser", "chrome");
user.setAttribute("$opt_bucketing_id", "bucketingId123");
// Option 2 – Pass attributes when creating the user
Map<String, Object> attributes = new HashMap<>();
attributes.put("ad_source", "my_campaign");
attributes.put("browser", "chrome");
// Bucketing ID can be passed in alone or with other attributes
attributes.put("$opt_bucketing_id", "bucketingId123");
OptimizelyUserContext user = optimizely.createUserContext(userId, attributes);
$experimentKey = 'my_experiment';
// For simplicity's sake, we are just using a hardcoded user id
$userId = 'user123';
// Option 1 – Create a user, then set attributes
$user = $optimizely->createUserContext($userID);
$user->setAttribute('is_logged_in', false);
$user->setAttribute('app_version', '1.3.2');
$user_.setAttribute('$opt_bucketing_id', 'bucketingId123');
// Option 2 – Pass attributes when creating the user
$attributes = array(
'device'=>'iPhone',
'lifetime'=> 24738388,
'is_logged_in'=> true,
'app_version' => '4.3.0-beta'
'$opt_bucketing_id' => 'bucketingId123'
);
$user = $optimizely->createUserContext($userId, $attributes);
from optimizely import optimizely
optimizely_client = optimizely.Optimizely("<YOUR_SDK_KEY")
experiment_key = "my_experiment"
# For simplicity's sake, we are just using a hardcoded user id
user_id = "user123"
# Optioin 1: Create a user, then set attributes
user = optimizely_client.create_user_context(user_id)
user.set_attribute("is_logged_in", False)
user.set_attribute("app_version", "1.3.2")
user.set_attribute("$opt_bucketing_id", "bucketingId123")
# Option 2 – Pass attributes when creating the user
attributes = {
"device": "iPhone",
"lifetime": 24738388,
"is_logged_in": True,
"$opt_bucketing_id": "bucketingId123"
}
user = optimizely_client.create_user_context(user_id, attributes)
experiment_key = 'my_experiment'
# For simplicity's sake, we are just using a hardcoded user id
user_id = 'user123'
attributes = {
'device' => 'iphone',
'ad_source' => 'my_campaign',
'$opt_bucketing_id' => 'bucketingId123'
};
# Option 1 – Create a user, then set attributes
user = optimizely.create_user_context(user_id)
user.set_attribute('is_logged_in', false)
user.set_attribute('app_version', '1.3.2')
user.set_attribute('$opt_bucketing_id', 'bucketingId123')
# Option 2 – Pass attributes when creating the user
attributes = {
'is_logged_in' => false,
'app_version' => '1.3.2'
'$opt_bucketing_id' => 'bucketingId123'
}
optimizely.create_user_context(user_id, attributes)
const experimentKey = 'my_experiment';
// For simplicity's sake, we are just using a hardcoded user id
const userId = 'user123';
// Option 1 – Create a user, then set attributes
const user = optimizely.createUserContext(userId);
user.setAttribute('is_logged_in', false);
user.setAttribute('app_version', '1.3.2');
user.setAttribute('$opt_bucketing_id': 'bucketingId123');
// Option 2 – Pass attributes when creating the user
const attributes = {
'ad_source': 'my_campaign',
'device': 'iphone',
'$opt_bucketing_id': 'bucketingId123'
}
const user = optimizely.createUserContext(userId, attributes);
For information about optimizelyUserContext
, see the SDK's reference:
Updated 6 months ago