On this page

Experiment Go SDK

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

This documentation is split into two sections for remote and local evaluation:

Remote evaluation

Implements fetching variants for a user through remote evaluation.

Install

Install the Go Server SDK using go get.

bash
go get github.com/amplitude/experiment-go-server

Quick start

  1. Initialize the experiment client
  2. Fetch variants for the user
  3. Access a flag's variant
go
// (1) Initialize the local evaluation client with a server deployment key.
client := remote.Initialize("<DEPLOYMENT_KEY>", nil)

// (2) Fetch variants for a user
user := &experiment.User{
  UserId:   "user@company.com",
  DeviceId: "abcdefg",
  UserProperties: map[string]interface{}{
    "premium": true,
  },
}
variants, err := client.Fetch(user)
if err != nil {
  // Handle error
}

// (3) Access a flag's variant
variant := variants["<FLAG_KEY>"]
if variant.Value == "on" {
    // Flag is on
} else {
    // Flag is off
}

Initialize

Initialize the SDK client in your server on startup. The deployment key argument you pass to the apiKey parameter must reside within the same project that you are sending analytics events to.

go
func Initialize(apiKey string, config *Config) *Client
ParameterRequirementDescription
apiKeyrequiredThe deployment key that authorizes fetch requests and determines which flags to evaluate for the user.
configoptionalThe client configuration used to customize SDK client behavior.
go
client := remote.Initialize("<DEPLOYMENT_KEY>", nil)

Configuration

Configure the SDK client upon initialization.

EU data center

If you're using Amplitude's EU data center, configure the ServerZone option on initialization.

NameDescriptionDefault Value
DebugSet to true to enable debug logging.false
LogLevelThe minimum log level to output. Options: Verbose, Debug, Info, Warn, Error, Disable. Go to custom logging.Error
LoggerProviderCustom logger implementation. Implement the LoggerProvider interface to integrate with your logging solution. Go to custom logging.defaultLoggerProvider which outputs to stdout
ServerZoneThe Amplitude data center to use. Either USServerZone or EUServerZone.USServerZone
ServerUrlThe host to fetch flag configurations from.https://api.lab.amplitude.com
FlagConfigPollingIntervalThe timeout for fetching variants in milliseconds. This timeout only applies to the initial request, not subsequent retries500 * time.Millisecond
RetryBackoff.FetchRetriesThe number of retries to attempt if a request to fetch variants fails.1
RetryBackoff.FetchRetryBackoffMinThe minimum (initial) backoff after a request to fetch variants fails. The SDK scales this delay by the RetryBackoff.FetchRetryBackoffScalar0
RetryBackoff.FetchRetryBackoffMaxThe maximum backoff between retries. If the scaled backoff becomes greater than the max, the SDK uses the max for all subsequent requests10 * time.Second
RetryBackoff.FetchRetryBackoffScalarScales the minimum backoff exponentially.1
RetryBackoff.FetchRetryTimeoutThe request timeout for retrying variant fetches.500 * time.Millisecond

Fetch

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

go
func (c *Client) Fetch(user *experiment.User) (map[string]experiment.Variant, error)
ParameterRequirementDescription
userrequiredThe user for whom to fetch variants.
go
user := &experiment.User{
    UserId:   "user@company.com",
    DeviceId: "abcdefg",
    UserProperties: map[string]interface{}{
        "premium": true,
    },
}
variants, err := client.Fetch(user)
if err != nil {
    // Handle error
}

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

go
variant := variants["<FLAG_KEY>"]
if variant.Value == "on" {
    // Flag is on
} else {
    // Flag is off
}

Fetch V2 with options

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

go
func (c *Client) FetchV2WithOptions(user *experiment.User, fetchOptions *experiment.FetchOptions) (map[string]experiment.Variant, error)
ParameterRequirementDescription
userrequiredThe user for whom to fetch variants.
fetchOptionsoptionalThe options for the fetch request. If nil, uses the server's default behavior (track assignment, don't track exposure).
go
user := &experiment.User{
    UserId:   "user@company.com",
    DeviceId: "abcdefg",
    UserProperties: map[string]interface{}{
        "premium": true,
    },
}
variants, err := client.FetchV2WithOptions(user, &experiment.FetchOptions{
    TracksAssignment: true,
    TracksExposure:   true,
})
if err != nil {
    // Handle error
}

FetchOptions

NameDescriptionDefault Value
TracksExposureIf true, the SDK tracks an exposure event for the fetched variants.false
TracksAssignmentIf true, the SDK tracks an assignment event for the fetched variants.true

Local evaluation

Implements evaluating variants for a user through local evaluation. If you plan to use local evaluation, you should understand the tradeoffs.

Install

Install the Go Server SDK using go get.

bash
go get github.com/amplitude/experiment-go-server

Quick start

  1. Initialize the local evaluation client.
  2. Start the local evaluation client.
  3. Evaluate a user.
go
// (1) Initialize the local evaluation client with a server deployment key.
client := local.Initialize("<DEPLOYMENT_KEY>", &local.Config{
 // (Recommended) Enable local evaluation cohort targeting.
 CohortSyncConfig: &local.CohortSyncConfig {
   ApiKey: "<API_KEY>",
   SecretKey: "<SECRET_KEY>"
 }
})

// (2) Start the local evaluation client.
err := client.Start()
if err != nil {
  panic(err)
}

  // (3) Evaluate a user.
user := &experiment.User{DeviceId: "abcdefg"}
variants, err := client.EvaluateV2(user, nil)
if err != nil {
  panic(err)
}

Initialize

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.

go
func Initialize(apiKey string, config *Config) *Client
ParameterRequirementDescription
apiKeyrequiredThe server deployment key that authorizes fetch requests and determines which flags to evaluate for the user.
configoptionalThe client configuration used to customize SDK client behavior.

Flag streaming

Use the StreamUpdates configuration to push flag config updates to the SDK (default false), instead of polling every FlagConfigPollingInterval milliseconds. Typically, the time for SDK to receive the update after saving is less than one second. The SDK reverts to polling if streaming fails. Configure FlagConfigPollingInterval configuration to set how much time flag configs take to update after they are modified (default 30s), as well for fallback.

Configuration

Configure the SDK client upon initialization.

EU data center

If you're using Amplitude's EU data center, configure the ServerZone option on initialization.

Config

NameDescriptionDefault Value
DebugSet to true to enable debug logging.false
LogLevelThe minimum log level to output. Options: Verbose, Debug, Info, Warn, Error, Disable. Go to custom logging.Error
LoggerProviderCustom logger implementation. Implement the LoggerProvider interface to integrate with your logging solution. Go to custom logging.defaultLoggerProvider which outputs to stdout
ServerZoneThe Amplitude data center to use. Either USServerZone or EUServerZone.USServerZone
ServerUrlThe host to fetch flag configurations from.https://api.lab.amplitude.com
FlagConfigPollingIntervalThe interval to poll for updated flag configs after calling Start()30 * time.Second
FlagConfigPollerRequestTimeoutThe timeout for the request made by the flag config poller10 * time.Second
AssignmentConfigDeprecated. Configuration for automatically tracking assignment events after an evaluation.nil
ExposureConfigConfiguration for tracking exposure events after an evaluation.nil
StreamUpdatesEnable streaming to replace polling for receiving flag config updates. Instead of polling every second, Amplitude servers push updates to SDK. Typically within one second. If the stream fails for any reason, it reverts to polling automatically and retry streaming after some interval.false
StreamServerUrlThe URL of the stream server.https://stream.lab.amplitude.com
StreamFlagConnTimeoutThe timeout for establishing a valid flag config stream. This includes time for establishing a connection to stream server and time for receiving initial flag configs.1500
CohortSyncConfigConfiguration to enable cohort downloading for local evaluation cohort targeting.nil

AssignmentConfig

NameDescriptionDefault Value
CacheCapacityThe maximum number of assignments stored in the assignment cache524288
ConfigOptions to configure the underlying Amplitude Analytics SDK used to track assignment events

ExposureConfig

NameDescriptionDefault Value
CacheCapacityThe maximum number of exposures stored in the exposure cache524288
ConfigOptions to configure the underlying Amplitude Analytics SDK used to track exposure events

CohortSyncConfig

NameDescriptionDefault Value
ApiKeyThe analytics API key and NOT the experiment deployment keyrequired
SecretKeyThe analytics secret keyrequired
MaxCohortSizeThe maximum size of cohort that the SDK downloads. Cohorts larger than this size won't download.2147483647
CohortPollingIntervalMillisThe interval, in milliseconds, to poll Amplitude for cohort updates (60000 minimum).60000
CohortServerUrlThe cohort server endpoint from which to fetch cohort data. For hitting the EU data center, set ServerZone to EUServerZone. Setting this value overrides ServerZone defaults.https://cohort-v2.lab.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.

go
func (c *Client) Start() error

You should await the result of Start() to ensure that flag configs are ready before calling Evaluate()

go
err := client.Start()
if err != nil {
    panic(err)
}

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 flag variants.

Exposure tracking

Set ExposureConfig to enable exposure tracking. Then, set TracksExposure to true in EvaluateOptions when calling EvaluateV2WithOptions().

go
func (c *Client) EvaluateV2(user *experiment.User, flagKeys []string) (map[string]experiment.Variant, error)
ParameterRequirementDescription
userrequiredThe user to evaluate.
flagKeysoptionalSpecific flags or experiments to evaluate. If nil or empty, the SDK evaluates all flags and experiments.
go
// The user to evaluate
user := &experiment.User{DeviceId: "abcdefg"}

// Evaluate all flag variants
allVariants, err := client.EvaluateV2(user, nil)
if err != nil {
    // Handle Error
}

// Evaluate a specific subset of flag variants
specificVariants, err := client.EvaluateV2(user, []string{
    "<FLAG_KEY_1>",
    "<FLAG_KEY_2>",
})

// Access a variant
variant := allVariants["<FLAG_KEY>"]
if variant.Value == "on" {
    // Flag is on
} else {
    // Flag is off
}

Evaluate V2 With Options

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 flag variants.

go
func (c *Client) EvaluateV2WithOptions(user *experiment.User, options *EvaluateOptions) (map[string]experiment.Variant, error)
ParameterRequirementDescription
userrequiredThe user to evaluate.
optionsoptionalThe options for the evaluation.
go
user := &experiment.User{DeviceId: "abcdefg"}
variants, err := client.EvaluateV2WithOptions(user, &local.EvaluateOptions{
    FlagKeys: []string{"flag-key-1", "flag-key-2"},
    TracksExposure: true,
})
if err != nil {
    // Handle Error
}

EvaluateOptions

NameDescriptionDefault Value
FlagKeysSpecific flags or experiments to evaluate. If nil or empty, the SDK evaluates all flags and experiments.nil
TracksExposureIf true, the SDK tracks an exposure event for the evaluated variants.false

Local evaluation cohort targeting

Since version 1.7.0, the local evaluation SDK client supports downloading cohorts for local evaluation targeting. Configure the CohortSyncConfig option with the analytics ApiKey and SecretKey on initialization to enable this support.

go
client := local.Initialize("<DEPLOYMENT_KEY>", &local.Config{
  // (Recommended) Enable local evaluation cohort targeting.
  CohortSyncConfig: &local.CohortSyncConfig {
    ApiKey: "<API_KEY>",
    SecretKey: "<SECRET_KEY>"
  }
})

Custom logging

Control log verbosity with the LogLevel configuration, or implement the LoggerProvider interface to integrate your own logger.

Log levels

The SDK supports these log levels:

  • Verbose: Detailed logging for deep debugging
  • Debug: Logging for development and troubleshooting
  • Info: General informational messages
  • Warn: Warning messages
  • Error: Error messages (default)
  • Disable: No logging

Custom logger

Implement the LoggerProvider interface to integrate your logging solution:

go
import "github.com/amplitude/experiment-go-server/logger"

type MyCustomLogger struct {
    // Your logger implementation
}

func (l *MyCustomLogger) Verbose(message string, args ...interface{}) {
    // Implement verbose logging
}

func (l *MyCustomLogger) Debug(message string, args ...interface{}) {
    // Implement debug logging
}

func (l *MyCustomLogger) Info(message string, args ...interface{}) {
    // Implement info logging
}

func (l *MyCustomLogger) Warn(message string, args ...interface{}) {
    // Implement warn logging
}

func (l *MyCustomLogger) Error(message string, args ...interface{}) {
    // Implement error logging
}

// Initialize with custom logger
client := local.Initialize("<DEPLOYMENT_KEY>", &local.Config{
    LogLevel: logger.Debug,
    LoggerProvider: &MyCustomLogger{},
})

Backward compatibility

The Debug configuration field is still supported. When set to true, it overrides LogLevel to Debug.

Was this helpful?