Skip to content

Dimensions

Dimensions are the contextual attributes that Flagship uses to make intelligent decisions about feature rollouts and experiments. They represent the "who," "where," and "how" of your application's traffic.

Evaluation Context

The evaluation context is a container for arbitrary contextual data that can be used as a basis for dynamic evaluation. Static data such as the host or an identifier for the application can be configured globally. Dynamic evaluation context, such as the IP address of the client in a web application, can be implicitly propagated or explicitly passed to during flag evaluation, and can be merged with static values.

Providing Evaluation Context

In server-side SDKs, values relevant for flag evaluation can be included in the evaluation context at multiple points: globally (on the top level API), on the client, and at the point of flag evaluation (invocation).

typescript
// add a value to the global context
OpenFeature.setContext({ myGlobalKey: 'myGlobalValue' });

// add a value to the client context
const client = OpenFeature.getClient();
client.setContext({ myClientKey: 'myClientValue' });

// add a value to the invocation context
const context: EvaluationContext = {
  myInvocationKey: 'myInvocationValue',
};
const boolValue = await client.getBooleanValue('boolFlag', false, context);
java
// add a value to the global context
OpenFeatureAPI api = OpenFeatureAPI.getInstance();
api.setEvaluationContext(new MutableContext().add("myGlobalKey", "myGlobalValue"));

// add a value to the client context
Client client = api.getClient();
client.setEvaluationContext(new MutableContext().add("myClientKey", "myClientValue"));

// add a value to the invocation context
EvaluationContext context = new MutableContext();
context.addStringAttribute("myInvocationKey", "myInvocationValue")
Boolean boolValue = client.getBooleanValue("boolFlag", false, context);
csharp
// add a value to the global context
Api api = Api.Instance;
api.SetContext(new EvaluationContextBuilder().Set("myGlobalKey", "myGlobalValue").Build());

// add a value to the client context
FeatureClient client = api.GetClient();
client.SetContext(new EvaluationContextBuilder().Set("myClientKey", "myClientValue").Build());

// add a value to the invocation context
var context = new EvaluationContext()
    .Set("myInvocationKey", "myInvocationValue")
    .Build();

var boolValue = await client.GetBooleanValue("boolFlag", false, context);
go
// add a value to the global context
openfeature.SetEvaluationContext(openfeature.NewEvaluationContext(
    "",
    map[string]interface{}{
        "myGlobalKey":  "myGlobalValue",
    },
))

// add a value to the client context
client := openfeature.NewClient("my-app")
client.SetEvaluationContext(openfeature.NewEvaluationContext(
    "", 
    map[string]interface{}{
        "myGlobalKey":  "myGlobalValue",
    },
))

// add a value to the invocation context
evalCtx := openfeature.NewEvaluationContext(
    "",
    map[string]interface{}{
        "myInvocationKey": "myInvocationValue",
    },
)
boolValue, err := client.BooleanValue("boolFlag", false, evalCtx)
php
// add a value to the global context
$api = OpenFeatureAPI.getInstance();
$api->setEvaluationContext(new EvaluationContext("targetingKey", ["myGlobalKey" => "myGlobalValue"]));

// add a value to the client context
$client = $api->getClient();
$client->setEvaluationContext(new EvaluationContext("targetingKey", ["myClientKey" => "myClientValue"]));

// add a value to the invocation context
$context = new EvaluationContext("targetingKey", ["myInvocationKey" => "myInvocationValue"]);

$boolValue = $client->getBooleanValue("boolFlag", false, $context);
python
# add a value to the global context
import openfeature.api
context = EvaluationContext("targetingKey", {"myGlobalKey": "myGlobalValue"})
openfeature.api.set_evaluation_context(context)

# add a value to the client context
client = api.get_client()
context = EvaluationContext("targetingKey", {"myClientKey": "myClientValue"})
client.set_evaluation_context(context)

# add a value to the invocation context
context = EvaluationContext("targetingKey", {"myInvocationKey": "myInvocationValue"})
bool_value = client.get_boolean_value("boolFlag", False, context)

Context Merging

At the point of flag evaluation, the evaluation context is merged, and duplicate values are overwritten as defined in the specification.

Static Context (Client-side)

In client-side SDKs, values relevant for flag evaluation are set on the OpenFeature API object. In these implementations, this is an asynchronous operation associated with provider reconciliation.

typescript
// add a value to the context
await OpenFeature.setContext({ myUserData: 'myUserValue' });

// the context is used for all feature flag evaluations automatically.
const boolValue = await client.getBooleanValue('boolFlag', false);

Common Examples

DimensionDescriptionExample Values
userIdUnique identifier for the useruser_123, abc-789
emailUser's email addressjane@example.com
planSubscription levelfree, pro, enterprise
regionGeographic or cloud regionus-west, eu-central
versionApplication or SDK version1.2.3, v2-alpha
deviceHardware platformios, android, web

Best Practices

Circular Structures

Do not include circular structures in the evaluation context to avoid evaluation issues. Circular structures are structures that reference themselves, either directly or indirectly.

Targeting Key

Flagship requires an identifier for the subject of flag evaluation to perform fractional evaluation or percentage-based rollouts deterministically.

The evaluation context includes an optional targeting key field for this purpose. The targeting key should contain a string uniquely identifying the subject (i.e.: a UUID, a hash of some user attribute such as an email, or the hostname of an application or service).

WARNING

No Targeting Key = No Percentages Without a targeting key, Flagship cannot calculate a deterministic bucket for the user. Percentage-based rules may either fail or behave non-deterministically depending on the SDK implementation. Always provide a targeting key if you plan to use percentage rollouts.

Distribution and Percentages

Percentage rollouts (e.g., "Rollout to 50%") are implemented as a modulo operation on the hash of the targeting key: hash(targetingKey) % 100.

Flagship applies a non-identity hash function to your targeting key. This means you do not need to ensure your keys are normally distributed yourself; you only need to ensure they are unique per user.

  • Good: UUIDs, User IDs, Emails (anything unique to the user).
  • Bad: Shared identifiers. For example, using the string "guest" for all anonymous users will put all guests in the same bucket (either all 0% or all 100%).
  • Contextual: If you are targeting a small segment (e.g., "Internal Team"), refer to the Small Target Size guidelines.

PII Considerations

Be thoughtful in your inclusion of personal data in the evaluation context. Such data is useful for targeting and dynamic evaluation.

IMPORTANT

Data Privacy Flagship performs all flag evaluations locally within your application's customized OpenFeature provider. We do not evaluate feature flags remotely, and we do not send your Evaluation Context (including any potential PII) to our backend. Your data stays with you.