k6
k6 is a JavaScript load testing framework for teams that treat performance as code. Use k6 when you want a test that does more than generate traffic: it scripts realistic user flows, enforces pass/fail criteria, and runs the same way locally and in continuous integration. In Harness Resilience Testing, you build a k6 test in the Load Test Studio and run it on your Kubernetes infrastructure.
k6 load tests run on Kubernetes infrastructure. To run on a Linux VM, use Locust.
What you can do with k6
Each goal below maps to a k6 capability you configure on this page:
- Gate a release on performance. Set a threshold such as "95th-percentile latency under 5000 ms" so a regression fails the run automatically.
- Reproduce a traffic surge. Use the Spike profile to ramp from zero to a high peak and back, mimicking a sale or launch.
- Find the breaking point. Use the Stress profile to push past expected load until the system degrades.
- Catch slow leaks. Use the Soak profile to hold steady load for hours and surface memory leaks or resource exhaustion.
- Model real journeys. Run multiple scenarios in parallel, such as a browse flow and a checkout flow, each with its own schedule.
- Drive very high load. Use distributed execution to split a test across runner pods for high concurrency.
Prerequisites
- Module access: Access to the Harness Resilience Testing module.
- Kubernetes infrastructure: A Kubernetes Chaos Infrastructure (v1.85.3 or later) with load testing enabled. Load testing is enabled by default on Kubernetes infrastructure.
- Environment: An environment created in your project for the infrastructure.
- Reachable target: Target application endpoints accessible from the test infrastructure.
Create a load test
- Navigate to Resilience Testing > Load Testing.
- Click + New Load Test.
Click the + New Load Test dropdown and select Try Sample Test to explore the flow with a pre-configured test before you build your own.
On the Overview tab, enter the test metadata and select where the test runs:
| Field | Description |
|---|---|
| Name | A descriptive identifier for the test. |
| Description | (Optional) What the test validates. |
| Tags | (Optional) Labels to organize tests. |
| Target Type | Select Kubernetes. The agent in the cluster runs k6 as a master pod and optional runner pods. |
| Load Test Infrastructure | Select a Kubernetes Chaos Infrastructure from the dropdown. |
| Load Test Type | Select K6. |
Click Next to proceed to Test Configuration.
Define the test
On the Test Configuration tab, choose how you want to define the test workload. The available controls change with the mode you select.
- Define test via UI
- Upload K6 script
- Using Custom Image
UI mode generates the k6 script for you from the requests, load profile, and thresholds you configure. Harness compiles them into a runnable k6 JavaScript file at execution time. Use this when you want a scripted test without writing JavaScript.
Each request is one HTTP call your virtual users make on every iteration. Click a row to expand and edit it. Each request supports:
| Field | Description |
|---|---|
| Method | GET, POST, PUT, DELETE, PATCH, HEAD, or OPTIONS. |
| URL / Name | The full endpoint URL and an optional label shown in results. |
| Query params | Key-value pairs appended to the URL. |
| Headers | HTTP request headers, such as Authorization and Content-Type. |
| Body | The request payload for methods that send data. |
| Checks | k6 checks that validate the response, for example that the status is 200. Failed checks are recorded in results. |
Click + Add request to add more calls to the scenario.
Upload a custom k6 JavaScript file when you need full control over user behavior, custom logic, or advanced k6 features. The script must export a default function: export default function () { ... }.
| Field | Description |
|---|---|
| Host URL | Passed to your script as __ENV.HOST_URL. Leave blank if your script uses hardcoded URLs. |
| k6 Script File | Drag and drop or browse to upload a .js file. Available globals are __ENV.HOST_URL and any variables you declare. |
import http from 'k6/http';
import { check, sleep } from 'k6';
export const options = {
stages: [
{ duration: '2m', target: 50 },
{ duration: '5m', target: 50 },
{ duration: '1m', target: 0 },
],
thresholds: {
http_req_duration: ['p(95)<5000'],
},
};
export default function () {
const res = http.get(`${__ENV.HOST_URL}/api/products`);
check(res, { 'status is 200': (r) => r.status === 200 });
sleep(1);
}
When your script declares its own scenarios, stages, or thresholds, k6 runs them as written. The Load Profile Overrides below apply only when the script does not define its own scenarios.
Use a prebuilt container image as the load test source. The image must contain the k6 binary and your script. This is useful when you maintain a packaged k6 setup outside Harness.
| Field | Description |
|---|---|
| Host URL | Passed to your script as __ENV.HOST_URL. Leave blank if your script uses hardcoded URLs. |
| Image | Container image reference (for example, my-registry/my-load-test:latest). |
| Entrypoint | Path to the .js script inside the image, passed as the positional argument to k6 run (for example, /scripts/script.js). |
| Load args | Additional CLI flags appended to the k6 run command (for example, --quiet, --out=json=/tmp/r.json). |
The Load Profile Overrides always take precedence over the image. If your script defines its own scenarios or stages, set Duration to their total run time so the complete test runs.
Shape the load with scenarios
The load profile controls how virtual users (VUs) are scheduled over time. In UI mode you build the profile visually with scenarios. In script and image modes you set lightweight overrides.
Start from a preset
Each preset configures a common scenario shape for a specific goal. Start from one and adjust, or build a custom profile:
| Preset | Shape | Use it to |
|---|---|---|
| Smoke | 1 VU for 1m | Verify the script and target work before a larger run. |
| Load | 50 VUs for 5m with ramp | Validate behavior at expected production load. |
| Stress | Ramp to 200 VUs | Find the breaking point beyond normal load. |
| Spike | 0 to 500 to 0 VUs | Reproduce a sudden traffic surge, such as a sale or launch. |
| Soak | 50 VUs for 2h | Detect memory leaks and degradation over a long run. |
| Custom | Your own stages | Define a bespoke ramp for your scenario. |
Configure scenarios and executors
A scenario is a named workload. Each scenario uses an executor that controls how its VUs are scheduled. Add more than one scenario to run workloads in parallel, for example a browse flow plus a checkout flow.
The ramping-vus executor ramps VUs up and down through stages and is the most common choice for gradual load. Configure each scenario with:
| Field | Description |
|---|---|
| Executor | How VUs are scheduled. ramping-vus ramps through stages. Go to the k6 executors reference to review other options. |
| Start VUs | Number of VUs active when the scenario begins. |
| Graceful stop | Time k6 waits for in-flight iterations to finish before stopping. |
| Stages | A list of duration and target VUs steps. k6 ramps linearly from the current VU count to each target over the duration. |
Click + Add stage to extend the ramp, or + Add scenario to run multiple workloads in parallel.
Override the profile for scripted tests
In Upload K6 script and Using Custom Image modes, the overrides apply only to k6's implicit default scenario and are ignored once your script declares its own scenarios or stages.
| Override | Description |
|---|---|
| Users | Concurrent virtual users to run. |
| Duration (seconds) | Total run time. For scripted scenarios or stages, enter their combined duration. |
| Iterations (cap) | Maximum iterations. Leave blank to use the value from the script. |
| RPS Limit | A global cap on requests per second that always applies. It is split evenly across replicas. |
Gate a release with pass/fail thresholds
Thresholds turn a load test into a gate. If any threshold fails, the run is marked Failed, which makes k6 well suited to release gates in continuous integration.
A threshold compares a metric statistic against a value:
| Field | Example | Description |
|---|---|---|
| Metric | http_req_duration | The k6 metric to evaluate. |
| Stat | p(95) | The statistic to compare, such as a percentile or average. |
| Operator | < | The comparison operator. |
| Value | 5000 | The threshold value (milliseconds for duration metrics). |
| Abort on fail | Off | Stop the run immediately when the threshold is breached, instead of finishing the test. |
The example above fails the run if the 95th-percentile request duration reaches 5000 ms. Click + Add threshold to add more criteria.
Add environment variables
Use environment variables to pass configuration and secrets into your test without hardcoding them. Reference them inside the script as __ENV.NAME. In UI mode, you can also reference them directly in request headers, URLs, and bodies as {{ENV.NAME}}. Secrets are encrypted at rest.
Scale with distributed execution
When a single pod cannot generate enough load, distributed execution runs k6 across multiple runner pods on Kubernetes. Each replica runs a slice of the load through k6's --execution-segment flag, so the total VUs and RPS are split evenly across pods.
| Replicas | Behavior |
|---|---|
| 0 or 1 | Single-pod mode. All VUs run on one pod. |
| 2 or more | The load is split across pods. Use this for more than 1,000 VUs or sustained high requests per second. |
Save and run the test
- Click Save to create the load test.
- Find your test in the Load Tests list, which shows Type, Users, Duration, and recent executions at a glance.
- Click the Run (▶) button to start an execution.
- Monitor real-time results during execution. A breached threshold marks the run as Failed.
Next steps
- Go to Analyze load test results to interpret throughput, error rate, response times, and threshold outcomes.
- Go to Locust to run a Python-based load test on Linux VM or Kubernetes.
- Go to Key concepts to review virtual users, load profiles, and thresholds.