Experiment Node.js SDK

Official documentation for Amplitude Experiment's server-side Node.js SDK implementation.

This documentation has separate sections for remote and local evaluation:

Remote evaluation

Implements fetching variants for a user via remote evaluation.

Install

Node version compatibility

The Node Server SDK works with Node 10+.

1npm install --save @amplitude/experiment-node-server

1yarn add @amplitude/experiment-node-server

Quick start

  1. Initialize the experiment client
  2. Fetch variants for the user
  3. Access a flag's variant
1import { Experiment } from '@amplitude/experiment-node-server';
2 
3// (1) Initialize the experiment client
4const experiment = Experiment.initializeRemote('<DEPLOYMENT_KEY>', {
5 fetchTimeoutMillis: 500,
6 fetchRetries: 1,
7 fetchRetryBackoffMinMillis: 0,
8 fetchRetryTimeoutMillis: 500,
9});
10 
11// (2) Fetch variants for a user
12const user = {
13 user_id: 'user@company.com',
14 device_id: 'abcdefg',
15 user_properties: {
16 'premium': true,
17 },
18};
19const variants = experiment.fetchV2(user);
20 
21// (3) Access a flag's variant
22const variant = variants['YOUR-FLAG-KEY'];
23if (variant?.value === 'on') {
24 // Flag is on
25} else {
26 // Flag is off
27}

Initialize remote

The SDK client should be initialized in your server on startup. The deployment key argument passed into the apiKey parameter must live within the same project that you are sending analytics events to.

1initializeRemote(apiKey: string, config?: RemoteEvaluationConfig): RemoteEvaluationClient
Parameter Requirement Description
apiKey required The deployment key which authorizes fetch requests and determines which flags should be evaluated for the user.
config optional The client configuration used to customize SDK client behavior.

!!!warning "Timeout & Retry Configuration"

Timeout and retry configuration

The default timeout and retry configuration options are too high for most server environments. Configure the timeout and retry options to best fit your performance requirements. If remote evaluation performance is too slow, consider using local evaluation.

1import { Experiment } from '@amplitude/experiment-node-server';
2 
3const experiment = Experiment.initializeRemote('<DEPLOYMENT_KEY>', config: {
4 fetchTimeoutMillis: 500,
5 fetchRetries: 1,
6 fetchRetryBackoffMinMillis: 0,
7 fetchRetryTimeoutMillis: 500,
8});

Configuration

The SDK client can be configured on initialization.

Name
Description Default Value
debug Enable additional debug logging. false
serverUrl The host to fetch variants from. https://api.lab.amplitude.com
fetchTimeoutMillis The timeout for fetching variants in milliseconds. This timeout only applies to the initial request, not subsequent retries 10000
fetchRetries The number of retries to attempt if a request to fetch variants fails. 8
fetchRetryBackoffMinMillis The minimum (initial) backoff after a request to fetch variants fails. This delay is scaled by the fetchRetryBackoffScalar 500
fetchRetryBackoffMaxMillis The maximum backoff between retries. If the scaled backoff becomes greater than the max, the max is used for all subsequent requests 10000
fetchRetryBackoffScalar Scales the minimum backoff exponentially. 1.5
fetchRetryTimeoutMillis The request timeout for retrying variant fetches. 10000

!!!info "EU Data Center"

EU data center

If you're using Amplitude's EU data center, configure the serverUrl option on initialization to https://api.lab.eu.amplitude.com

Fetch

Fetches variants for a user and returns the results. This function remote evaluates the user for flags associated with the deployment used to initialize the SDK client.

1fetchV2(user: ExperimentUser): Promise<Variants>
Parameter Requirement Description
user required The user to remote fetch variants for.
1const user = {
2 user_id: 'user@company.com',
3 device_id: 'abcdefg',
4 user_properties: {
5 'premium': true,
6 },
7};
8const variants = await experiment.fetchV2(user);

After fetching variants for a user, you may to access the variant for a specific flag.

1const variant = variants['YOUR-FLAG-KEY'];
2if (variant?.value === 'on') {
3 // Flag is on
4} else {
5 // Flag is off
6}

Local evaluation

Implements evaluating variants for a user via local evaluation. If you plan on using local evaluation, you should understand the tradeoffs.

Install

Install the Node.js Server SDK with npm or yarn.

1npm install --save @amplitude/experiment-node-server

1yarn add @amplitude/experiment-node-server

Quick start

  1. Initialize the local evaluation client.
  2. Start the local evaluation client.
  3. Evaluate a user.
1import { Experiment } from '@amplitude/experiment-node-server';
2 
3// (1) Initialize the local evaluation client with a server deployment key.
4const experiment = Experiment.initializeLocal('<DEPLOYMENT_KEY>');
5 
6// (2) Start the local evaluation client.
7await experiment.start();
8 
9// (2) Evaluate a user.
10const user = { device_id: 'abcdefg' };
11const variants = experiment.evaluateV2(user);

Initialize Local

Initializes a local evaluation client.

Server deployment key

You must initialize the local evaluation client with a server deployment key to get access to local evaluation flag configs.

1initializeLocal(apiKey: string, config?: LocalEvaluationConfig): LocalEvaluationClient
Parameter Requirement Description
apiKey required The server deployment key which authorizes fetch requests and determines which flags should be evaluated for the user.
config optional The client configuration used to customize SDK client behavior.

Flag polling interval

Use the flagConfigPollingIntervalMillis configuration to determine the time flag configs take to update once modified (default 30s).

Flag streaming

Use the streamUpdates configuration to get flag config updates pushed to SDK (default false), instead of polling every flagConfigPollingIntervalMillis milliseconds. The time for SDK to receive the update after saving is generally under 1 second. It will fallback to polling if streaming failed. Configure flagConfigPollingIntervalMillis configuration as well for fallback.

Configuration

You can configure the SDK client on initialization.

LocalEvaluationConfig

Name
Description Default Value
debug Set to true to enable debug logging. false
serverUrl The host to fetch flag configurations from. https://api.lab.amplitude.com
bootstrap Bootstrap the client with a map of flag key to flag configuration {}
flagConfigPollingIntervalMillis The interval (in milliseconds) to poll for updated flag configs after calling start() 30000
assignmentConfig Configuration for automatically tracking assignment events after an evaluation. null
streamUpdates Enable streaming to replace polling for receiving flag config updates. Instead of polling every second, our servers push updates to SDK generally within a second. If stream fails for any reason, it will fallback to polling automatically and retry streaming after some interval. false
streamServerUrl The stream server url to stream from. https://stream.lab.amplitude.com
streamFlagConnTimeoutMillis The timeout for establishing a valid flag config stream. This includes time for a connection to be established to stream server and time for receiving initial flag configs. 1500

AssignmentConfig

Name
Description Default Value
apiKey The analytics API key and NOT the experiment deployment key required
cacheCapacity The maximum number of assignments stored in the assignment cache 65536
Analytics SDK Options Options to configure the underlying Amplitude Analytics SDK used to track assignment events

!!!info "EU Data Center"

EU data center

If you're using Amplitude's EU data center, configure the serverUrl option on initialization to https://api.lab.eu.amplitude.com

If you opted in for streaming flag config updates, configure the streamServerUrl option on initialization to https://stream.lab.eu.amplitude.com

Start

Start the local evaluation client, pre-fetching local evaluation mode flag configs for evaluation and starting the flag config poller at the configured interval.

1start(): Promise<void>

You should await the result of start() to ensure that flag configs are ready to be used before calling evaluateV2()

1await experiment.start();

Evaluate

Executes the evaluation logic using the flags pre-fetched on start(). You must give evaluate a user object argument. You can optionally pass an array of flag keys if you require only a specific subset of required flag variants.

!!!tip "Automatic Assignment Tracking"

Automatic assignment tracking

Set assignmentConfig to automatically track an assignment event to Amplitude when evaluateV2() is called.

1evaluateV2(user: ExperimentUser, flagKeys?: string[]): Record<string, Variant>
Parameter Requirement Description
user required The user to evaluate.
flagKeys optional Specific flags or experiments to evaluate. If undefined, null, or empty, all flags and experiments are evaluated.
1// The user to evaluate
2const user = { device_id: 'abcdefg' };
3 
4// Evaluate all flag variants
5const allVariants = experiment.evaluateV2(user);
6 
7// Evaluate a specific subset of flag variants
8const specificVariants = experiment.evaluateV2(user, [
9 'my-local-flag-1',
10 'my-local-flag-2',
11]);

Access Amplitude cookies

If you're using the Amplitude Analytics SDK on the client-side, the Node.js server SDK provides an AmplitudeCookie class with convenience functions for parsing and interacting with the Amplitude identity cookie. This is useful for ensuring that the Device ID on the server matches the Device ID set on the client, especially if the client hasn't yet generated a Device ID.

1import { AmplitudeCookie } from '@amplitude/experiment-node-server';
2 
3app.use((req, res, next) => {
4 const { query, cookies, url, path, ip, host } = req
5 
6 // grab amp device id if present
7 const ampCookieName = AmplitudeCookie.cookieName('amplitude-api-key');
8 let deviceId = null;
9 if (cookies[ampCookieName]) {
10 deviceId = AmplitudeCookie.parse(cookies[ampCookieName]).device_id;
11 }
12 if (!deviceId) {
13 // deviceId doesn't exist, set the Amplitude Cookie
14 deviceId = random22CharBase64String();
15 const ampCookieValue = AmplitudeCookie.generate(deviceId);
16 res.cookie(ampCookieName, ampCookieValue, {
17 domain: '.your-domain.com', // this should be the same domain used by the Amplitude JS SDK
18 maxAge: 365 * 24 * 60 * 60 * 1000, // this is currently the same as the default in the Amplitude JS SDK, can be modified
19 sameSite: 'Lax'
20 });
21 }
22 
23 next()
24});
Was this page helpful?

Thanks for your feedback!

June 4th, 2024

Need help? Contact Support

Visit Amplitude.com

Have a look at the Amplitude Blog

Learn more at Amplitude Academy

© 2024 Amplitude, Inc. All rights reserved. Amplitude is a registered trademark of Amplitude, Inc.