Skip to main content
Setting up an interleaving experiment touches four places: your ranking code, your event tracking, your Data Source, and GrowthBook. If you already run A/B tests through GrowthBook, the new pieces are one SDK call, one exposure query, and two columns on your engagement events.

Before you start

  • Plan. Interleaving is in private beta for Enterprise customers. Ask your GrowthBook account team to enable it.
  • SDKs. The JavaScript, React, and Node.js SDKs support interleaving from version 2.0.0. Other SDKs are not supported yet.
  • Warehouses. The analysis unnests a JSON array in SQL. Redshift and Vertica are not supported yet.
  • Rankers. Your ranking code must return a ranked list for a given config object. The config is authored in GrowthBook and handed to your code unchanged.

Step 1: Call interleave() in your code

Register the plugin on your GrowthBook instance and replace the call that fetches your ranked list with interleave().
interleave() evaluates targeting for the user. If they are in the experiment it calls getList() with each ranker’s config, drafts the two lists into one, and fires the exposure. Otherwise it serves the first ranker’s list. It returns: Every option, return field, and fallback path is documented in the API reference at the bottom of this page.

Rules for rankingId and result

  • One rankingId per query. A new search or page load is a new id. A filter change is a new query. Pagination continues the same draft: fetch the full lists once and page through result.
  • A user-selected sort is not a ranking. Pass enabled: false.
  • Never re-sort or re-filter result. It breaks the recorded positions and which items count as competitive. Apply diversity caps, pinned items, and filters inside each ranker’s list, before the merge.

Node.js and React

With the multi-user GrowthBookClient, register the plugin on the client and call interleave() with the user-scoped instance from createScopedInstance(). In React, register the plugin on the GrowthBook instance you pass to GrowthBookProvider and call interleave() with the instance from useGrowthBook().

Step 2: Track exposures

The plugin’s onExposure callback fires once per interleaved impression. Send it to your warehouse the same way you send “Experiment Viewed” events, keeping items as a JSON array in one column.
The InterleaveExposure and InterleavedItem types in the API reference describe each field.

Step 3: Track engagement

Every engagement event you want to measure and attribute to a ranker, such as a click, add-to-cart, or order, must carry two extra properties:
  • item_id (required): the same id getItemId() returns.
  • ranking_id (required for paired analysis): the impression the item was engaged with from. Spreading trackingProps adds it, along with experiment_id.
For example, a React list that logs one click per item:
An event with a ranking_id is credited to the exact list that showed the item. Preference analysis works from item_id alone, which fits conversions logged by a system that never sees the list, such as an order recorded days later. See InterleaveTrackingProps in the API reference for the exact keys.

Step 4: Set up the Data Source

Add an Interleaving Exposure Query

An interleaving experiment reads exposures through an Interleaving Exposure Query, not an Experiment Assignment Query, because the shape is different: one row per impression with the item detail in a JSON array. Add one from your Data Source’s settings page under Interleaving Exposure Queries.
The query must return these columns: Each query declares one identifier type. Click Test query to check that the required columns come back. One query can serve every experiment on the Data Source.

Add item_id and ranking_id to your Fact Tables

Interleaving analyzes mean and proportion Fact Metrics. The Fact Table behind each metric must expose the engagement properties from Step 3 as columns with these exact names: Add them to the Fact Table’s SQL:
Then check the Fact Table’s column list in GrowthBook. Columns are detected when the SQL is saved; if ranking_id is missing or marked deleted, refresh the columns. GrowthBook validates the columns when you save the experiment and again on every results update, and names the missing column in the error. Two things to know about ranking_id:
  • Null is fine for preference analysis. Events logged by a system that never sees the list, such as orders, can leave ranking_id null. Preference analysis ignores the column. Paired analysis skips those rows, so do not add paired analysis to such a metric.
  • It must match exactly. The analysis joins on string equality with the exposure’s ranking_id. Keep the id as the SDK emitted it: no prefix, no case change, no truncation.
Row filters on the metric apply as usual, so one Fact Table of engagement events can back many metrics.

Step 5: Create the experiment in GrowthBook

Go to Experiments → Interleaving and click Add Interleaving Experiment. A ranker config is any JSON object your code understands. For the example above:
This lets you iterate on your ranking algorithm without shipping new code, so long as you expose a sufficiently rich config interface.

Via the REST API

Everything above is available through the REST API. A minimal create request:
Then start it.

Step 6: Start it and check the data

An interleaving experiment is a draft until you start it. Starting adds it to the SDK payload for the enabled environments, and only exposures between start and stop are analyzed. Stopping or archiving removes it from SDK payloads immediately; results stay available. Shortly after starting, click Update on the Results tab. If no results appear, check that:
  1. Exposure rows exist with the experiment’s tracking key as experiment_id.
  2. The SDK connection serves the environment you enabled, and the SDK version supports interleaving.
  3. Engagement events carry item_id, and ranking_id for metrics with paired analysis.
  4. Engagement timestamps are at or after the exposure’s timestamp. If exposures are batched and land late, use a column that records when the list was shown rather than when the event was received.
To understand the results, see Understanding interleaving results.

API reference

The key functions and interfaces the SDK exports for interleaving, from @growthbook/growthbook/plugins. The type exports are shown as declarations, in the style of a .d.ts file.