Skip to main content

Run an Experiment

Beta

Experimentation is in beta.

Once an experiment is running, Flagsmith serves the variations automatically through the flag. Your application has two jobs:

  1. Record exposures: tell Flagsmith when an identity actually experienced a variation.
  2. Record conversion events: send the events your metrics aggregate.

Instrument your application​

Remote evaluation only

Experiments currently work with remote evaluation only. Support for local evaluation is in progress.

Users must be identified. Exposures and conversion events are joined per identity, so use the same identifier for flags and events.

SDK overview​

Install or upgrade​

npm install @flagsmith/flagsmith@^12.4.0

Initialise​

Enable events when you create the client, with the environment key you already use for flags. Events accept the client-side key and server-side keys.

When self-hosting, also point the SDK at your Flagsmith API and your event ingestion service, as in the commented lines below. Otherwise the SDK sends events to Flagsmith Cloud. To deploy the event ingestion service, see Experimentation in the Helm chart.

The SDKs buffer events and send them in batches, by default every 10 seconds. Send what is left before your application exits, as shown in each tab.

import flagsmith from '@flagsmith/flagsmith';

await flagsmith.init({
environmentID: 'YOUR_CLIENT_SIDE_ENVIRONMENT_KEY',
enableEvents: true,
// Self-hosted only:
// api: 'https://flagsmith.example.com/api/v1/',
// eventProcessorConfig: { eventsApiUrl: 'https://events.flagsmith.example.com/' },
});
await flagsmith.identify('user_42');

// Before a server-side render responds, or before the page unloads
await flagsmith.flushEvents();

eventProcessorConfig requires enableEvents: true; init throws without it.

Record exposures​

An exposure is the moment an identity is served a variation; it is what enrols them in the results. Getting the experiment flag evaluates it and records the exposure in one call.

import flagsmith from '@flagsmith/flagsmith'; // the client from Initialise

const flag = flagsmith.getExperimentFlag('checkout_button');
// ...render based on flag.value

The experiment flag call records the exposure as soon as it evaluates the flag, so use it where the user actually experiences the change. If you evaluate in one place and display in another, don't use it. Evaluate with the SDK's normal flag call instead, which records nothing, then record the exposure yourself at the point of display. Only record it for identities enrolled in the experiment:

import flagsmith from '@flagsmith/flagsmith'; // the client from Initialise

// Evaluate without recording an exposure
const flag = flagsmith.getAllFlags().checkout_button;

// ...later, at the point of display
if (flag?.experiment?.inExperiment) {
flagsmith.trackExposureEvent('checkout_button', { value: flag.variant });
}
Self-hosted

Events are sent to https://events.api.flagsmith.com/ unless you say otherwise. If you host Flagsmith yourself, point the SDK at your own event ingestion service with eventProcessorConfig.eventsApiUrl in JavaScript, or event_processor_config=EventProcessorConfig(events_api_url=...) in Python. See deploying experimentation.

Exposures are deduplicated per identity: each identity is counted once, in the variation it saw first, so recording an exposure more than once is safe.

Track conversions​

Send a named event, optionally with a numeric value, traits and metadata. The name must match your metric's event name.

import flagsmith from '@flagsmith/flagsmith'; // the client from Initialise

flagsmith.trackEvent('purchase', { value: 99.5 });

The event name is case-sensitive and must exactly match the metric's configured event name. Unmatched events are silently ignored. Conversions are attributed post-exposure: an identity's events only count after its first exposure.

Troubleshooting​

The SDKs skip events silently rather than throw. If the Exposures panel stays empty, check that:

  • The environment has a connected warehouse. The event ingestion service rejects events for environments without one.
  • The user is identified. Exposures without an identity are skipped.
  • Every variation of the flag has a label. Exposures are attributed by label, so a variation without one, for example one created through the API without a key, is not counted.
  • The identity is inside the experiment's rollout. Identities outside it are not enrolled and record no exposure.
  • Buffered events were sent before your application exited. See Initialise.
  • Event names match your metrics exactly, including case.

To see why an event was skipped, turn on your SDK's debug logging.

While it runs​

  • The flag is locked while the experiment is running.
  • Monitor enrolment on the experiment page's Exposures panel to confirm data is arriving.
  • You can edit the rollout from the experiment page, but changing it mid-experiment can affect the statistical validity of your results.