Experiment JVM SDK
Official documentation for Amplitude Experiment's server-side JVM SDK implementation. This SDK may be used in either Java or Kotlin server-side implementations.
This documentation has separate sections for remote and local evaluation:
Remote evaluation¶
Implements fetching variants for a user via remote evaluation.
Install¶
Install the JVM Server SDK using Gradle.
implementation "com.amplitude:experiment-jvm-server:<VERSION>"
implementation("com.amplitude:experiment-jvm-server:<VERSION>")
Quick Start
// (1) Initialize the remote evaluation client with a server deployment key.
val experiment = Experiment.initializeRemote("<DEPLOYMENT_KEY>")
// (2) Fetch variants for a user
val user = ExperimentUser.builder()
.userId("user@company.com")
.deviceId("abcdefg")
.userProperty("premium", true)
.build()
val variants = try {
experiment.fetch(user).get()
} catch (e: Exception) {
e.printStackTrace()
return
}
// (3) Access a flag's variant
val variant = variants["<FLAG_KEY>"]
if (variant?.value == "on") {
// Flag is on
} else {
// Flag is off
}
// (1) Initialize the remote evaluation client with a server deployment key.
RemoteEvaluationClient experiment =
Experiment.initializeRemote("<DEPLOYMENT_KEY>");
// (2) Fetch variants for a user
ExperimentUser user = ExperimentUser.builder()
.userId("user@company.com")
.deviceId("abcdefg")
.userProperty("premium", true)
.build();
Map<String, Variant> variants;
try {
variants = experiment.fetch(user).get();
} catch (Exception e) {
e.printStackTrace();
return;
}
// (3) Access a flag's variant
Variant variant = variants.get("<FLAG_KEY>");
if (Variant.valueEquals(variant, "on")) {
// Flag is on
} else {
// Flag is off
}
Not getting the expected variant result for your flag? Make sure your flag is activated, has a deployment set, and has users allocated.
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.
fun initializeRemote(
apiKey: String,
config: RemoteEvaluationConfig = RemoteEvaluationConfig()
): RemoteEvaluationClient
@Nonnull
public RemoteEvaluationClient initializeRemote(
@Nonnull String apiKey,
@Nonnull RemoteEvaluationConfig config
);
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. |
val experiment = Experiment.initializeRemote("<DEPLOYMENT_KEY>")
RemoteEvaluationClient experiment = Experiment.initializeRemote("<DEPLOYMENT_KEY>");
Configuration¶
The SDK client can be configured on initialization.
Configuration Options
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 |
fetchTimeoutMillis |
The timeout for fetching variants in milliseconds. This timeout only applies to the initial request, not subsequent retries | 500 |
fetchRetries |
The number of retries to attempt if a request to fetch variants fails. | 1 |
fetchRetryBackoffMinMillis |
The minimum (initial) backoff after a request to fetch variants fails. This delay is scaled by the fetchRetryBackoffScalar |
0 |
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 |
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.
fun fetch(user: ExperimentUser): CompletableFuture<Map<String, Variant>>
@Nonnull
public CompletableFuture<Map<String, Variant>> fetch(@Nonnull ExperimentUser user);
Parameter | Requirement | Description |
---|---|---|
user |
required | The user to remote fetch variants for. |
val user = ExperimentUser.builder()
.userId("user@company.com")
.deviceId("abcdefg")
.userProperty("premium", true)
.build()
val variants = try {
experiment.fetch(user).get()
} catch (e: Exception) {
e.printStackTrace()
return
}
ExperimentUser user = ExperimentUser.builder()
.userId("user@company.com")
.deviceId("abcdefg")
.userProperty("premium", true)
.build();
Map<String, Variant> variants;
try {
variants = experiment.fetch(user).get();
} catch (Exception e) {
e.printStackTrace();
return;
}
After fetching variants for a user, you may to access the variant for a specific flag.
val variant = variants["<FLAG_KEY>"]
if (variant?.value == "on") {
// Flag is on
} else {
// Flag is off
}
Variant variant = variants.get("<FLAG_KEY>");
if (Variant.valueEquals(variant, "on")) {
// Flag is on
} else {
// Flag is off
}
Local evaluation¶
Implements evaluating variants for a user via local evaluation. If you plan on using local evaluation, you should understand the tradeoffs.
Local Evaluation Mode
The local evaluation client can only evaluation flags which are set to local evaluation mode.
Install¶
Install the JVM Server SDK using Gradle.
implementation "com.amplitude:experiment-jvm-server:<VERSION>"
implementation("com.amplitude:experiment-jvm-server:<VERSION>")
Quick Start
// (1) Initialize the local evaluation client with a server deployment key.
val experiment = Experiment.initializeLocal("<DEPLOYMENT_KEY>")
// (2) Start the local evaluation client.
experiment.start()
// (3) Evaluate a user.
val user = ExperimentUser.builder()
.userId("user@company.com")
.deviceId("abcdefg")
.userProperty("premium", true)
.build()
val variants = experiment.evaluate(user)
// (1) Initialize the local evaluation client with a server deployment key.
LocalEvaluationClient experiment = Experiment.initializeLocal("<DEPLOYMENT_KEY>");
// (2) Start the local evaluation client.
experiment.start();
// (3) Evaluate a user.
ExperimentUser user = ExperimentUser.builder()
.userId("user@company.com")
.deviceId("abcdefg")
.userProperty("premium", true)
.build();
Map<String, Variant> variants = experiment.evaluate(user);
Not getting the expected variant result for your flag? Make sure your flag is activated, has a deployment set, and has users allocated.
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.
fun initializeLocal(
apiKey: String,
config: LocalEvaluationConfig = LocalEvaluationConfig(),
): LocalEvaluationClient
@Nonnull
public LocalEvaluationClient initializeLocal(
@Nonnull String apiKey,
@Nonnull LocalEvaluationConfig config
);
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).
Configuration¶
You can configure the SDK client on initialization.
Configuration Options
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 |
flagConfigPollingIntervalMillis |
The interval to poll for updated flag configs after calling Start() |
30000 |
flagConfigPollerRequestTimeoutMillis |
The timeout for the request made by the flag config poller | 10000 |
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
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.
fun start()
public void start();
You should wait for start()
to return before calling evaluate()
to ensure that flag configs are available for use in evaluation.
Evaluate¶
Executes the evaluation logic using the flags pre-fetched on start()
. Evaluate must be given a user object argument and can optionally be passed an array of flag keys if only a specific subset of required flag variants are required.
fun evaluate(user: ExperimentUser, flagKeys: List<String> = listOf()): Map<String, Variant>
@Nonnull
public Map<String, Variant> evaluate(@Nonnull experimentUser, @Nonnull List<String> flagKeys);
Parameter | Requirement | Description |
---|---|---|
user |
required | The user to evaluate. |
flagKeys |
optional | Specific flags or experiments to evaluate. If empty, all flags and experiments are evaluated. |
// The user to evaluate
val user = ExperimentUser.builder()
.userId("user@company.com")
.deviceId("abcdefg")
.userProperty("premium", true)
.build()
// Evaluate all flag variants
val allVariants = experiment.evaluate(user)
// Evaluate a specific subset of flag variants
val specificVariants = experiment.evaluate(user, listOf(
"<FLAG_KEY_1>",
"<FLAG_KEY_2>",
))
// Access a variant
val variant = allVariants["<FLAG_KEY>"]
if (variant?.value == "on") {
// Flag is on
} else {
// Flag is off
}
// The user to evaluate
ExperimentUser user = ExperimentUser.builder()
.userId("user@company.com")
.deviceId("abcdefg")
.userProperty("premium", true)
.build();
// Evaluate all flag variants
Map<String, Variant> allVariants = experiment.evaluate(user);
// Evaluate a specific subset of flag variants
Map<String, Variant> specificVariants = experiment.evaluate(user,
List.of("<FLAG_KEY_1>", "<FLAG_KEY_2>"));
// Access a variant
Variant variant = allVariants.get("<FLAG_KEY>");
if (Variant.valueEquals(variant, "on")) {
// Flag is on
} else {
// Flag is off
}