Skip to main content

Feature flags configuration and bucketing

When you update a feature flag configuration or turn it on or off, SDKs can obtain the updated configuration from the Cloudflare Content Delivery Network (CDN) using either polling or streaming. Polling is the default option while streaming is a premium option. Kameleoon designs its SDKs to comply with a zero latency policy. The SDK doesn’t require additional remote server calls to activate and bucket users in a feature flag. Even a fast remote server call adds a minimum of 20 ms of latency to the app, and depending on several factors, this delay can increase to hundreds of milliseconds or completely block the app loading for the end user. To prevent this added latency, Kameleoon SDKs assign visitors to experiments locally.
For client-side SDKs, which run on the user’s device, the app must fetch the active feature flag configurations at the start of the session. This requires a remote call with an associated callback, which means app code that uses the SDK can’t run experiments or apply feature flags before this callback finishes executing.

Polling (default)

In this mode, the SDK sends a request to the CDN at regular intervals (by default, every 60 minutes) to retrieve the most recent configuration. You can customize the interval in the SDK configuration using the refresh_interval_minute (or refresh_interval) parameter.
When intervals are moderately spaced, updating the configuration consumes very little memory and network resources.
For web client-side SDKs, the polling strategy includes local caching logic:
  1. Initial Load: When a visitor opens a web page, the SDK first attempts to load the configuration from the cache (if available).
  2. Background Update: If the refresh_interval has elapsed, the SDK performs a background request to update the configuration and refreshes the cache.
  3. Cache Validity: The SDK considers cached configuration valid for 1.5 hours from the last successful update. If the visitor opens a page within this 1.5-hour window, the SDK uses the cached version. Otherwise, it ignores the cache and makes a new request immediately.
This caching strategy ensures faster page loads and minimal network usage, while still keeping configuration reasonably fresh.Suppose you set refresh_interval to 15 minutes and a feature flag exposes a user. If you turn off the feature flag 10 minutes later and the same user returns to the website 20 minutes later:
  • The SDK will first load the configuration from cache (still showing the flag as active).
  • Simultaneously, it will make a background request to fetch the updated configuration and refresh the cache.
  • This design prioritizes performance, ensuring quick page loads while asynchronously syncing with the updated config.
So, even though there’s a short window where a user might see stale configuration (depending on the interval), the SDK quickly updates it in the background. The SDK applies the updated configuration the next time the visitor opens a page.

Impact on newly launched experiments and feature flags

dataFileCacheTtl and dataFileRefreshInterval together determine how quickly the SDK evaluates visitors against a newly launched experiment or feature flag’s configuration. Visitors whose cached data file has already aged past dataFileCacheTtl, or who have no cached data file yet, receive the new configuration immediately, because initialize() blocks until a fresh data file arrives. Visitors whose cached data file is still within dataFileCacheTtl keep evaluating against the previous configuration until that cache ages past dataFileCacheTtl, or until a background refresh completes and they load another page. As a result, with the default dataFileCacheTtl of 90 minutes, traffic entering a newly launched experiment ramps up gradually instead of reaching full volume immediately. For example, a newly launched experiment might expose about 40% of its eventual targeted population in the first hour after launch, about 57% by the second hour, and more than 95% by the third hour, once enough visitors’ cached data files have aged past that 90-minute window. No visitor is permanently excluded from the experiment. Each one joins after their device fetches the updated configuration.
When you compare Kameleoon exposure numbers to another analytics tool right after launching a campaign, expect a ramp-up period of roughly dataFileCacheTtl minutes (90 by default) before exposure numbers stabilize and match the targeted population. A lower exposed-visitor count during that window doesn’t mean the SDK drops or mistargets those visitors. If your use case needs a faster start, lower dataFileCacheTtl (keep it higher than dataFileRefreshInterval to avoid adding unnecessary blocking requests to page load), or discuss the streaming option with Kameleoon support, which bypasses the cache model entirely for the SDK data file.
A setup that pairs a server-side or edge SDK with getEngineTrackingCode() and the Engine.js tracking script can still show a similar ramp-up in tracked results, driven by the separate browser cache for Engine.js itself. See Engine.js caching behavior for details.

Streaming (premium option)

The real-time streaming mode allows the SDK to automatically apply the new configuration without any delay. When you enable streaming, the Kameleoon SDK receives notification of any changes to the configuration in real time, thanks to server-sent events (SSE). Main benefits:
  • Update the configuration immediately (no waiting for the next polling cycle).
  • Use less network traffic than polling at short intervals. Streaming doesn’t send periodic requests. It opens the connection once and keeps it permanently open, ready to receive data.
Availability:
  • Real-time streaming is a premium option that requires a subscription. To activate it on a Kameleoon account, contact the Customer Success Manager or email support@kameleoon.com.
  • The PHP SDK doesn’t support streaming due to technical constraints. It can’t listen for configuration updates in a non-blocking way because the PHP SDK doesn’t persist between requests. Each request creates a new SDK instance that destroys itself immediately after it receives a response.
  • The real-time streaming mode isn’t compatible with serverless edge compute platforms.
  • For other languages, see the SDK compatibility matrix for the minimum supported version in the preferred language.

Data storage

Kameleoon designs its SDKs for optimal performance and user experience by managing visitor data locally, either on the server or directly on the device, instead of fetching it from a remote source. Kameleoon stores all visitor data relevant to experiments and feature flags locally, including experiment assignments, segment data, and any custom data added using methods like addData() or fetched from the server with getRemoteVisitorData(). Where the SDK stores this data and its lifespan differs between server-side and client-side SDKs.

Server-side SDKs

For server-side SDKs, the SDK stores visitor data in the server’s volatile memory (RAM), which provides fast access for experiment and feature flag evaluations. The SDK organizes data as a map, using unique visitorCode values as keys.
  • Session-based storage: The SDK retains data in memory only for the duration of a user’s active session, which ends by default after 30 minutes of inactivity (no page views or clicks). All data collected during the session expires at the same time.
    • session_duration parameter: Adjust session duration using the session_duration parameter in the SDK configuration. This parameter lets the Kameleoon session align with your app’s server-side session management.
Increasing session_duration will require the SDK to allocate more RAM to store the increased visitor data
  • Data loss on server restart: Because the SDK stores data in RAM, it’s lost if the app server restarts. Usually, data loss isn’t a concern, since Kameleoon typically retrieves important visitor data (like user IDs or attributes) from a persistent database and reassigns it to the visitor upon a new request.
  • Retrieving data from previous visits: The getRemoteVisitorData() method lets you retrieve custom data collected during a visitor’s previous visit. This method automatically associates the last data entry for a visitor, eliminating the need to call addData() again.

Client-side SDKs

As opposed to server-side SDKs, client-side SDKs utilize persistent local storage on the user’s device. This mechanism ensures that visitor data persists across browser sessions, app restarts, and even device reboots. The specific storage mechanism varies by platform:
  • iOS: UserDefaults
  • Android: SharedPreferences
  • JavaScript/TypeScript: LocalStorage
    • Note for JS SDK: The kameleoonVisitorCode is also shared via cookies to ensure seamless data continuity and communication with the Kameleoon app file (engine.js).
  • React Native: MMKV Storage
Unlike server-side SDKs which use a global session_duration, client-side SDKs don’t operate on a session-based expiry for all data. Instead, they use either targetingDataCleanupInterval or data_expiration_interval_minute to control how long the SDK stores each piece of data.
  • targetingDataCleanupInterval/data_expiration_interval_minute: These parameters determine the individual lifespan of each specific data entry. By default, the SDK stores data indefinitely (until explicitly cleared) to ensure consistent user experiences across visits. Set this parameter to a specific number of minutes if you need individual data points to expire after a certain time.
  • Data persistence: This fundamental difference means that data persists even if the user closes the browser tab, navigates away from the site, or closes the mobile app.
  • Naming convention rationale: The difference in parameter terminology (session_duration versus data_expiration_interval_minute) reflects the underlying storage philosophy. session_duration governs the overall lifetime of all data within a server-side session. data_expiration_interval_minute allows granular control over the lifespan of each specific piece of data stored persistently on the client.

Edge SDKs

Edge SDKs, deployed through serverless edge compute starter kits, don’t retain visitor data between requests the way server-side or client-side SDKs do. An edge platform can destroy and recreate a worker instance at any time, so a session_duration setting has no durable memory to apply to, and an edge worker might not see a later request from the same visitor. Because an edge worker can’t retain visitor data on its own, your integration is responsible for making visitor data available to the edge worker on every request, typically by passing it in as a cookie and calling addData() before evaluating a feature flag or experiment. See Edge targeting constraints for the full explanation and a code example.

Domain list

The Kameleoon SDKs require access to a set of URIs that provide specific services to the SDK. If you are restricting access and need to explicitly whitelist domains, make sure that the Kameleoon SDKs can reach the following domains:
The domain for your Kameleoon scripts may vary from one project to another. Kameleoon may host your projects on either kameleoon.eu or kameleoon.io depending on their creation date. Make sure you use the domain displayed in your project in the Kameleoon App.