Running switchback tests¶
Info
Learn the concepts and fundamentals of switchback tests in the Explanation page.
A switchback test is an experiment that runs in the background and compares the results of two instances: baseline vs. candidate. The experiment switches back and forth between the two instances, when a run is made to the app, hence the name.
Included in this how-to guide are instructions on how to interact with
switchback tests using methods on the Application
class. Go the reference section to see all the available parameters for each
method.
Create a switchback test¶
Use the Application.new_switchback_test method to
create a new switchback test for an application. A switchback test
requires you to define the number of units that it is going to run for, via
the units keyword argument. Each unit is a time duration in minutes, defined
by the unit_duration_minutes keyword argument. Lastly, you must define two
instances to compare against each other, using the comparison
keyword argument as a TestComparisonSingle
object: a baseline and a candidate.
Here is an example that creates a new switchback test for an application.
import os
import nextmv
from nextmv import cloud
from nextmv.cloud import TestComparisonSingle
client = cloud.Client(api_key=os.getenv("NEXTMV_API_KEY"))
app = cloud.Application.get(client=client, id="uncanny-rodent")
switchback_test = app.new_switchback_test(
comparison=TestComparisonSingle(
baseline_instance_id="production",
candidate_instance_id="staging",
),
unit_duration_minutes=2,
units=5,
)
nextmv.write(switchback_test.to_dict())
{
"id": "switchback-ds8itzqx",
"name": "switchback-ds8itzqx",
"description": "",
"created_at": "2026-07-29T04:09:16.269205Z",
"updated_at": "2026-07-29T04:09:16.269205Z",
"status": "draft",
"comparison": {
"baseline_instance_id": "production",
"candidate_instance_id": "staging"
},
"plan": {
"units": [
{
"duration_minutes": 2.0,
"instance_id": "production",
"index": 0
},
{
"duration_minutes": 2.0,
"instance_id": "staging",
"index": 1
},
{
"duration_minutes": 2.0,
"instance_id": "staging",
"index": 2
},
{
"duration_minutes": 2.0,
"instance_id": "staging",
"index": 3
},
{
"duration_minutes": 2.0,
"instance_id": "production",
"index": 4
}
]
}
}
The call above will create a random ID, and use the same identifier for the
switchback test’s name. The name of the test is used as a
human-readable label. You can use the switchback_test_id and/or name
keyword arguments to specify a custom ID and name for the switchback
test. For example:
import os
import nextmv
from nextmv import cloud
from nextmv.cloud import TestComparisonSingle
client = cloud.Client(api_key=os.getenv("NEXTMV_API_KEY"))
app = cloud.Application.get(client=client, id="uncanny-rodent")
switchback_test = app.new_switchback_test(
comparison=TestComparisonSingle(
baseline_instance_id="production",
candidate_instance_id="staging",
),
unit_duration_minutes=2,
units=5,
switchback_test_id="fluffy-switchback-test",
name="Fluffy Switchback Test",
)
nextmv.write(switchback_test.to_dict())
{
"id": "fluffy-switchback-test",
"name": "Fluffy Switchback Test",
"description": "",
"created_at": "2026-07-29T04:09:21.149085Z",
"updated_at": "2026-07-29T04:09:21.149085Z",
"status": "draft",
"comparison": {
"baseline_instance_id": "production",
"candidate_instance_id": "staging"
},
"plan": {
"units": [
{
"duration_minutes": 2.0,
"instance_id": "staging",
"index": 0
},
{
"duration_minutes": 2.0,
"instance_id": "production",
"index": 1
},
{
"duration_minutes": 2.0,
"instance_id": "production",
"index": 2
},
{
"duration_minutes": 2.0,
"instance_id": "staging",
"index": 3
},
{
"duration_minutes": 2.0,
"instance_id": "staging",
"index": 4
}
]
}
}
The Application.new_switchback_test method
creates a switchback test in draft mode. Once the test is
created, you must start it.
Start a switchback test¶
As mentioned above, when a switchback test is created, it is in draft mode. A switchback test must be started so that it can begin executing runs and collecting data. There are two ways to start a switchback test:
- Using the
startkeyword argument (adatetimeobject) with theApplication.new_switchback_testmethod. This will start the switchback test at the scheduled time. - Using the
Application.start_switchback_testmethod. This will start the switchback test as soon as the method is called.
As an example, here is how to start a switchback test using the
Application.start_switchback_test method:
Once a switchback test has started, you can stop it at any time or wait for it to complete based on the termination events defined when the test was created.
Get a switchback test¶
Info
The best way to view and interact with switchback test results is in the Nextmv Console.
Use the
Application.switchback_test_metadata method
to retrieve the metadata for a switchback test, using the switchback
test ID. The method returns a
SwitchbackTestMetadata object.
Once the status of the switchback test is completed, you can get the
results using the Application.switchback_test
method. The method returns a SwitchbackTest
object, whose output includes the runs that were made for the test. If
the test hasn't completed, you can still get partial results.
A switchback test that has already started can be stopped at any
time, or it will stop automatically when the termination events are fulfilled.
Once a switchback test is stopped, then its status will move to
completed.
{
"id": "fluffy-switchback-test",
"name": "Fluffy Switchback Test",
"description": "",
"created_at": "2026-07-29T04:09:21.149085Z",
"updated_at": "2026-07-29T04:09:25.335058Z",
"status": "started",
"started_at": "2026-07-29T04:09:25.332407Z",
"comparison": {
"baseline_instance_id": "production",
"candidate_instance_id": "staging"
},
"plan": {
"start": "2026-07-29T04:09:25.332407Z",
"units": [
{
"duration_minutes": 2.0,
"instance_id": "staging",
"index": 0
},
{
"duration_minutes": 2.0,
"instance_id": "production",
"index": 1
},
{
"duration_minutes": 2.0,
"instance_id": "production",
"index": 2
},
{
"duration_minutes": 2.0,
"instance_id": "staging",
"index": 3
},
{
"duration_minutes": 2.0,
"instance_id": "staging",
"index": 4
}
]
},
"runs": [
{
"id": "staging-0NLvQUPDg",
"user_email": "sebastian@nextmv.io",
"name": "",
"description": "",
"created_at": "2026-07-29T04:10:02.896050Z",
"application_id": "uncanny-rodent",
"application_instance_id": "staging",
"application_version_id": "v0.0.2",
"run_type": {
"definition_id": "",
"reference_id": ""
},
"execution_class": "6c9500mb870s",
"runtime": "python-3_11",
"status_v2": "succeeded",
"queuing_priority": 6,
"queuing_disabled": false,
"metrics": {
"status": "succeeded",
"indicators": [
{
"name": "value",
"value": 1.23
},
{
"name": "metadata.duration",
"value": 4.322
}
]
},
"options": {
"details": "true"
},
"options_summary": [
{
"name": "details",
"value": "true",
"source": "version"
}
]
},
{
"id": "staging-FtxDQUEDR",
"user_email": "sebastian@nextmv.io",
"name": "",
"description": "",
"created_at": "2026-07-29T04:09:59.979877Z",
"application_id": "uncanny-rodent",
"application_instance_id": "staging",
"application_version_id": "v0.0.2",
"run_type": {
"definition_id": "",
"reference_id": ""
},
"execution_class": "6c9500mb870s",
"runtime": "python-3_11",
"status_v2": "succeeded",
"queuing_priority": 6,
"queuing_disabled": false,
"metrics": {
"status": "succeeded",
"indicators": [
{
"name": "value",
"value": 1.23
},
{
"name": "metadata.duration",
"value": 4.402
}
]
},
"options": {
"details": "true"
},
"options_summary": [
{
"name": "details",
"value": "true",
"source": "version"
}
]
},
{
"id": "staging-8-ovQ8Evg",
"user_email": "sebastian@nextmv.io",
"name": "",
"description": "",
"created_at": "2026-07-29T04:09:57.112480Z",
"application_id": "uncanny-rodent",
"application_instance_id": "staging",
"application_version_id": "v0.0.2",
"run_type": {
"definition_id": "",
"reference_id": ""
},
"execution_class": "6c9500mb870s",
"runtime": "python-3_11",
"status_v2": "succeeded",
"queuing_priority": 6,
"queuing_disabled": false,
"metrics": {
"status": "succeeded",
"indicators": [
{
"name": "value",
"value": 1.23
},
{
"name": "metadata.duration",
"value": 4.527
}
]
},
"options": {
"details": "true"
},
"options_summary": [
{
"name": "details",
"value": "true",
"source": "version"
}
]
},
{
"id": "staging-z_5vQUEvg",
"user_email": "sebastian@nextmv.io",
"name": "",
"description": "",
"created_at": "2026-07-29T04:09:54.241438Z",
"application_id": "uncanny-rodent",
"application_instance_id": "staging",
"application_version_id": "v0.0.2",
"run_type": {
"definition_id": "",
"reference_id": ""
},
"execution_class": "6c9500mb870s",
"runtime": "python-3_11",
"status_v2": "succeeded",
"queuing_priority": 6,
"queuing_disabled": false,
"metrics": {
"status": "succeeded",
"indicators": [
{
"name": "value",
"value": 1.23
},
{
"name": "metadata.duration",
"value": 4.609
}
]
},
"options": {
"details": "true"
},
"options_summary": [
{
"name": "details",
"value": "true",
"source": "version"
}
]
}
]
}
You can list all switchback tests in the application using the
Application.list_switchback_tests method.
import json
import os
from nextmv import cloud
client = cloud.Client(api_key=os.getenv("NEXTMV_API_KEY"))
app = cloud.Application.get(client=client, id="uncanny-rodent")
switchback_tests = app.list_switchback_tests()
print(json.dumps([switchback_test.to_dict() for switchback_test in switchback_tests[:2]], indent=2))
[
{
"id": "fluffy-switchback-test",
"name": "Fluffy Switchback Test",
"description": "",
"created_at": "2026-07-29T04:09:21.149085Z",
"updated_at": "2026-07-29T04:09:25.335058Z",
"status": "started",
"started_at": "2026-07-29T04:09:25.332407Z",
"comparison": {
"baseline_instance_id": "production",
"candidate_instance_id": "staging"
}
},
{
"id": "switchback-ds8itzqx",
"name": "switchback-ds8itzqx",
"description": "",
"created_at": "2026-07-29T04:09:16.269205Z",
"updated_at": "2026-07-29T04:09:16.269205Z",
"status": "draft",
"comparison": {
"baseline_instance_id": "production",
"candidate_instance_id": "staging"
}
}
]
Stop a switchback test¶
A switchback test will continue to execute until it stops, which is equivalent to it being completed. There are two ways to stop a switchback test:
- Using the
unit_duration_minutesandunitskeyword arguments with theApplication.new_switchback_testmethod. Termination events will cause the switchback test to stop. - Using the
Application.stop_switchback_testmethod. This will stop the switchback test as soon as the method is called.
When using the Application.stop_switchback_test method, you must use the
intent keyword argument (a StopIntent value) to
track if you want to complete or cancel the switchback test. As an
example, here is how to stop a switchback test and mark it as completed:
Update a switchback test¶
You can update attributes of a switchback test with the
Application.update_switchback_test method,
such as its:
- Name
- Description
The method returns a SwitchbackTest object. You cannot update the ID of a
switchback test.
import os
import nextmv
from nextmv import cloud
client = cloud.Client(api_key=os.getenv("NEXTMV_API_KEY"))
app = cloud.Application.get(client=client, id="uncanny-rodent")
switchback_test = app.update_switchback_test(
switchback_test_id="fluffy-switchback-test",
name="Updated Switchback Test Name",
description="Updated description for the switchback test",
)
nextmv.write(switchback_test.to_dict())
Delete a switchback test¶
Warning
Deleting a switchback test is irreversible. All the data associated with the switchback test will be permanently deleted.
Delete a switchback test using the
Application.delete_switchback_test method.