Disclaimer: This website requires Please enable JavaScript in your browser settings for the best experience.

Dev guideRecipesAPI ReferenceChangelog
Dev guideAPI ReferenceRecipesChangelogUser GuideGitHubDev CommunityOptimizely AcademySubmit a ticketLog In
Dev guide

Configure CMAB for the Android SDK

Contextual Multi-Armed Bandit (CMAB) features, including cache and service endpoint, can be configured in the Feature Experimentation Android SDK.

👍

Beta

CMAB for Feature Experimentation is in beta. Contact your Customer Success Manager for more information.

The CMAB cache stores variation assignments to reduce latency and minimize API calls to the CMAB service.

Prerequisites

  • Android SDK version 5.1.0 or higher.
  • A CMAB-enabled experiment in your Optimizely project.

Minimum SDK version

5.1.0

Description

When a user is bucketed into a CMAB experiment, the Android SDK makes an API call to the CMAB service to determine which variation to show. To improve performance and reduce latency, the Android SDK 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, the SDK uses an in-memory Least Recently Used (LRU) cache with a maximum size of 100 entries and a TTL of 30 minutes (1,800 seconds). You can customize these settings or provide your own cache implementation.

Configuration options

Configure CMAB when building your OptimizelyManager.

Default configuration

The Android SDK uses the following default values when no custom configuration is provided:

SettingDefault ValueDescription
Cache Size100Maximum number of cached decisions.
Cache TTL1,800 seconds (30 minutes)Time-to-live for cache entries.
CmabClientDefaultCmabClientThis network client implements the CmabClient interface to fetch real-time decisions from Optimizely's CMAB service.
CmabPredictionEndpointhttps://prediction.cmab.optimizely.com/predict/%sThis setting overrides the default prediction endpoint URL. It must include a %s placeholder for the CMAB experiment ID.

Configuration methods

Set cache size

OptimizelyManager.builder().withCmabCacheSize(int cacheSize)

Parameters

  • cacheSize (int) – Maximum number of decisions to cache. Must be a positive integer.

Example

OptimizelyManager optimizelyManager = OptimizelyManager.builder()
          .withCmabCacheSize(50)
          .build(context);

Set cache TTL

DefaultCmabService.builder().withCmabCacheTimeout(int interval, TimeUnit timeUnit)

Parameters

  • interval (int) – the interval.
  • timeUnit (TimeUnit) – the time unit of the timeout argument.

Example

OptimizelyManager optimizelyManager = OptimizelyManager.builder()
          .withCmabCacheTimeout(10, TimeUnit.SECONDS)
          .build(context);

Set custom CMABClient

DefaultCmabService.builder().withCmabClient(CmabClient cmabClient)

Parameters

  • cmabClient (CmabClient) – The custom implementation of the CmabClient interface.

Example

OptimizelyManager optimizelyManager = OptimizelyManager.builder()
          .withCmabClient(customCmabClient)
          .build(context);

Set custom CMABPredictionEndpoint

DefaultCmabService.builder().withCmabPredictionEndpoint(String endpoint)

Parameters

  • endpoint (String) – The custom CMAM prediction endpoint.

Example

OptimizelyManager optimizelyManager = OptimizelyManager.builder()
          .withCmabPredictionEndpoint("https://example-prediction.com/%s")
          .build(context);

Cache behavior

Automatic cache invalidation

The cache is automatically invalidated when the following occurs:

  • The cached entry's TTL expires.
  • CMAB attribute values change for a user (detected through MD5 hash comparison).
  • The IGNORE_CMAB_CACHE decide option is used.
  • The INVALIDATE_USER_CMAB_CACHE decide option is used.
  • The RESET_CMAB_CACHE decide option is used.

CMAB-specific decide options

Control cache behavior on a per-decision basis using decide options.

// Ignore cache for this decision (always fetch fresh)
user.decideAsync(
	"my-flag", 
  Arrays.asList(OptimizelyDecideOption.IGNORE_CMAB_CACHE),
	(OptimizelyDecision decision) -> {
      Log.d("Samples","[CMAB] async decision for cmab: " + decision.toString());
  }
);

// Invalidate cached decision for this user and experiment
user.decideAsync(
	"my-flag", 
  Arrays.asList(OptimizelyDecideOption.INVALIDATE_USER_CMAB_CACHE),
	(OptimizelyDecision decision) -> {
      Log.d("Samples","[CMAB] async decision for cmab: " + decision.toString());
  }
);

// Clear entire CMAB cache
user.decideAsync(
	"my-flag", 
  Arrays.asList(OptimizelyDecideOption.RESET_CMAB_CACHE),
	(OptimizelyDecision decision) -> {
      Log.d("Samples","[CMAB] async decision for cmab: " + decision.toString());
  }
);

Available CMAB decideoOptions

Decide optionDescription
IGNORE_CMAB_CACHEBypass cache and fetch a fresh decision from CMAB service.
INVALIDATE_USER_CMAB_CACHERemove cached decision for this user and experiment before deciding.
RESET_CMAB_CACHEClear all entries from the CMAB cache before deciding.