Configure the CMAB cache for Agent
Configure caching behavior for Contextual Multi-Armed Bandit (CMAB) decisions in Optimizely Agent.
BetaCMAB for Feature Experimentation is in beta. Contact your Customer Success Manager for more information.
The CMAB cache for Optimizely Agent stores variation assignments to reduce latency and minimize API calls to the CMAB service.
Prerequisites
- Optimizely Agent version 4.3.0 or higher.
- A CMAB-enabled experiment in your Optimizely Feature Experimentation project.
Description
When a user is bucketed into a CMAB experiment, Optimizely Agent makes an API call to the CMAB service to determine which variation to display. To improve performance and reduce latency, Optimizely Agent caches these decisions based on the following:
- User ID.
- Experiment ID.
- CMAB attribute values.
The cache is automatically invalidated when CMAB attributes change for a user, ensuring fresh decisions when context changes.
By default, Optimizely Agent uses an in-memory least recently sed (LRU) cache with a size of 10,000 entries and a timeout of 30 minutes. You can customize these settings in your config.yaml configuration file, or configure Redis for shared caching across multiple Optimizely Agent instances.
Parameters
Configure CMAB caching in your config.yaml file under the client.cmab section.
Configuration structure
client:
cmab:
requestTimeout: 10s
## URL template for CMAB prediction API with %s placeholder for experimentId
predictionEndpoint: "https://prediction.cmab.optimizely.com/predict/%s"
cache:
default: "in-memory"
services:
in-memory:
size: 10000
timeout: 30m
redis:
host: "localhost:6379"
password: ""
database: 0
timeout: 30m
retryConfig:
maxRetries: 1
initialBackoff: 100ms
maxBackoff: 10s
backoffMultiplier: 2.0Top-level CMAB parameters
Configure the following parameters in client.cmab:
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
requestTimeout | duration | No | 10s | Timeout for CMAB API requests. Increase for slower network connections. |
predictionEndpoint | string | No | https://prediction.cmab.optimizely.com/predict/%s | URL template for CMAB prediction service. Override for testing or staging environments. |
Cache parameters
Configure the following cache behavior in client.cmab.cache:
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
default | string | No | "in-memory" | Default cache service to use. Options include "in-memory" or "redis". |
In-memory service parameters
Configure in-memory cache in client.cmab.cache.services.in-memory with the following parameters:
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
size | int | No | 10000 | Maximum number of decisions to cache. Increase for applications with many users or experiments. |
timeout | duration | No | 30m | How long cache entries remain valid. Lower values ensure fresher decisions but increase API calls. |
Redis service parameters
Configure the Redis cache in client.cmab.cache.services.redis with the following parameters:
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
host | string | Yes | - | Redis server address. For example "localhost:6379". |
password | string | No | "" | Redis password for authentication. |
database | int | No | 0 | Redis database number to use. |
timeout | duration | No | 30m | How long cache entries remain valid. |
Retry parameters
Configure the exponential backoff retry behavior in client.cmab.retryConfig with the following parameters:
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
maxRetries | int | No | 1 | Maximum number of retry attempts for failed CMAB API requests. 1 means up to two total attempts. One initial + one retry. |
initialBackoff | duration | No | 100ms | Initial wait time before first retry. |
maxBackoff | duration | No | 10s | Maximum wait time between retries. |
backoffMultiplier | float64 | No | 2.0 | Multiplier for exponential backoff (each retry waits longer). |
NoteDuration values can be specified in seconds (for example "5s"), minutes (for example, "30m"), or milliseconds (for example, "500ms").
Examples
Basic configuration
Adjust the cache size and timeout for your application's needs.
# config.yaml
client:
cmab:
# Allow 15 seconds for CMAB API calls
requestTimeout: 15s
predictionEndpoint: "https://prediction.cmab.optimizely.com/predict/%s"
cache:
default: "in-memory"
services:
in-memory:
# Cache up to 5000 decisions
size: 5000
# Refresh cache every 10 minutes
timeout: 10mHigh-traffic configuration
For applications with many users and CMAB experiments.
# config.yaml
client:
cmab:
requestTimeout: 10s
predictionEndpoint: "https://prediction.cmab.optimizely.com/predict/%s"
cache:
default: "in-memory"
services:
in-memory:
# Increase cache size for more users
size: 20000
# Keep decisions cached for 1 hour
timeout: 1h
retryConfig:
# Retry up to 5 times for resilience
maxRetries: 5
initialBackoff: 200ms
maxBackoff: 30s
backoffMultiplier: 2.0Low-latency configuration
For applications requiring frequently updated decisions.
# config.yaml
client:
cmab:
# Shorter timeout for faster failures
requestTimeout: 5s
predictionEndpoint: "https://prediction.cmab.optimizely.com/predict/%s"
cache:
default: "in-memory"
services:
in-memory:
size: 10000
# Refresh decisions every 5 minutes
timeout: 5m
retryConfig:
# Fewer retries for faster responses
maxRetries: 0
initialBackoff: 50ms
maxBackoff: 5s
backoffMultiplier: 2.0Redis configuration
For multi-instance deployments with shared caching.
# config.yaml
client:
cmab:
requestTimeout: 10s
predictionEndpoint: "https://prediction.cmab.optimizely.com/predict/%s"
cache:
default: "redis"
services:
redis:
host: "localhost:6379"
password: ""
database: 0
# Keep decisions cached for 30 minutes
timeout: 30mMaking decide requests
After Optimizely Agent is configured, use the /v1/decide endpoint to get CMAB decisions.
curl -X POST https://your-agent-host:8080/v1/decide \
-H "X-Optimizely-SDK-Key: your-sdk-key" \
-H "Content-Type: application/json" \
-d '{
"userId": "user123",
"userAttributes": {
"age": 25,
"location": "US"
},
"decideOptions": ["INCLUDE_REASONS"],
"decisionContext": {
"flagKey": "my-cmab-flag"
}
}'Response.
{
"userId": "user123",
"flagKey": "my-cmab-flag",
"enabled": true,
"variationKey": "variation_a",
"ruleKey": "cmab-rule-1",
"reasons": [
"Returning cached CMAB decision",
"User \"user123\" bucketed into variation \"variation_a\" by CMAB service"
],
"variables": {
"color": "blue",
"size": "large"
}
}Cache behavior
Cache invalidation
The cache is automatically invalidated when
- The cached entry's timeout period expires.
- CMAB attribute values change for a user (detected through attribute hash comparison).
- The
/v1/resetendpoint is called (for testing).
Decide options
Control decision behavior using decideOptions in your /v1/decide request.
curl -X POST https://your-agent-host:8080/v1/decide \
-H "X-Optimizely-SDK-Key: YOUR_SDK_KEY" \
-H "Content-Type: application/json" \
-d '{
"userId": "user123",
"decideOptions": ["INCLUDE_REASONS", "EXCLUDE_VARIABLES"],
"decisionContext": {
"flagKey": "my-cmab-flag"
}
}'Available options
DISABLE_DECISION_EVENT– Skip sending impression events for this decision.INCLUDE_REASONS– Include detailed reasoning for the decision in the response.EXCLUDE_VARIABLES– Exclude variable values from the response.ENABLED_FLAGS_ONLY– Only return decisions for enabled flags.IGNORE_USER_PROFILE_SERVICE– Skip user profile service lookup for this decision.IGNORE_CMAB_CACHE– Bypass CMAB cache and fetch a fresh decision from CMAB service.INVALIDATE_USER_CMAB_CACHE– Invalidate cached CMAB decisions for this user and experiment before deciding.RESET_CMAB_CACHE– Clear all CMAB cache entries before deciding (affects all users).
CMAB-specific decide options
The following decide options control CMAB cache behavior:
IGNORE_CMAB_CACHE
IGNORE_CMAB_CACHEUse this option to bypass the cache and always fetch a fresh decision from the CMAB service.
Use case – One-off requests where you need the absolute freshest decision from the CMAB service.
Example scenario
# VIP user - always get fresh CMAB decision, never use cache.
curl -X POST https://your-agent-host:8080/v1/decide \
-H "X-Optimizely-SDK-Key: YOUR_SDK_KEY" \
-H "Content-Type: application/json" \
-d '{
"userId": "vip_user_456",
"userAttributes": {
"tier": "platinum"
},
"decideOptions": ["IGNORE_CMAB_CACHE"],
"decisionContext": {
"flagKey": "my-cmab-flag"
}
}'INVALIDATE_USER_CMAB_CACHE
INVALIDATE_USER_CMAB_CACHEUse this option to invalidate cached CMAB decisions for this specific user and experiment before making a new decision.
Use case – When you know the user's context has changed but the attributes in your current request don't reflect it yet.
Example scenario
# User just made a purchase. Their behavior profile changed.
# But we are sending same attributes. We want fresh CMAB decision.
curl -X POST https://your-agent-host:8080/v1/decide \
-H "X-Optimizely-SDK-Key: YOUR_SDK_KEY" \
-H "Content-Type: application/json" \
-d '{
"userId": "user123",
"userAttributes": {
"country": "us",
"age": 25
},
"decideOptions": ["INVALIDATE_USER_CMAB_CACHE"],
"decisionContext": {
"flagKey": "my-cmab-flag"
}
}'RESET_CMAB_CACHE
RESET_CMAB_CACHEUse this option to clear the entire CMAB cache (all users and all experiments) before making a decision.
Use case – Clear entire CMAB cache when you need to ensure all users get fresh decisions.
Example scenario
# CMAB model was just retrained. Clear all cached decisions.
curl -X POST https://your-agent-host:8080/v1/decide \
-H "X-Optimizely-SDK-Key: YOUR_SDK_KEY" \
-H "Content-Type: application/json" \
-d '{
"userId": "any_user",
"decideOptions": ["RESET_CMAB_CACHE"],
"decisionContext": {
"flagKey": "my-cmab-flag"
}
}'
Warning
RESET_CMAB_CACHEaffects all users and should be used sparingly, typically only in testing or when CMAB models are updated.
Decision reasons
When you include "INCLUDE_REASONS" in your decide options, Optimizely Agent provides detailed reasons that help you understand how the decision was made, including cache behavior.
Example request with reasons
curl -X POST https://your-agent-host:8080/v1/decide \
-H "X-Optimizely-SDK-Key: YOUR_SDK_KEY" \
-H "Content-Type: application/json" \
-d '{
"userId": "user123",
"userAttributes": {
"age": 25
},
"decideOptions": ["INCLUDE_REASONS"],
"decisionContext": {
"flagKey": "my-cmab-flag"
}
}'Example response with reasons
{
"userId": "user123",
"flagKey": "my-cmab-flag",
"enabled": true,
"variationKey": "variation_a",
"reasons": [
"Returning cached CMAB decision",
"User \"user123\" bucketed into variation \"variation_a\" by CMAB service"
]
}The reasons array includes the following information:
- Whether the decision was served from cache or fetched from the CMAB service.
- Cache invalidation events.
- Bucketing results.
- Any errors encountered during decision-making.
Reset endpoint
Agent provides a /v1/reset endpoint to clear the client cache, including CMAB decisions. This is primarily used for testing.
Request
curl -X POST https://your-agent-host:8080/v1/reset \
-H "X-Optimizely-SDK-Key: your-sdk-key"Response
{
"result": true
}
ImportantThe reset endpoint clears the entire client cache for the specified SDK key, including the following:
- CMAB cache.
- Datafile cache.
- All other cached data.
This ensures a clean state for testing but should not be used in production.
Custom CMAB endpoint
For testing or staging environments, you can override the default CMAB prediction endpoint (https://prediction.cmab.optimizely.com/predict/%s).
With config.yaml
config.yaml# config.yaml
client:
cmab:
predictionEndpoint: "https://staging-cmab.example.com/predict/%s"With an environment variable
export OPTIMIZELY_CMAB_PREDICTIONENDPOINT="https://staging-cmab.example.com/predict/%s"
NoteEnvironment variable takes priority over the
config.yamlsetting.
Multi-instance deployments
In-memory cache
The in-memory cache is isolated to each Agent instance and cannot be shared. For multi-instance deployments, consider using Redis for shared caching.
Redis cache
Agent supports Redis for shared caching across multiple instances. Configure Redis in your config.yaml file.
# config.yaml
client:
cmab:
predictionEndpoint: "https://prediction.cmab.optimizely.com/predict/%s"
cache:
default: "redis"
services:
redis:
host: "localhost:6379"
password: ""
database: 0
timeout: 30mRedis availability
If Redis becomes unavailable
- New decisions fall back to CMAB API calls (no caching).
- Existing cached entries become inaccessible.
- Agent continues serving decisions (degraded performance).
Updated about 1 hour ago