Guide
Defining and Validating HTTP Response Time SLAs with k6 Thresholds
Learn how to add k6 thresholds for HTTP latency and error‑rate SLAs, run the test, interpret the pass/fail output, and recover when a threshold is violated.
Published by Tasadduq Burney
22 Aug 2025, 19:53 UTC
3 min120.7K views0

Desired outcome
Verify that, during a load test, the 95th percentile of HTTP request latency stays below a defined SLA (for example, 500 ms) and that the overall error rate remains under 1 %. If either condition is violated, the test should exit with a non‑zero status so that CI pipelines can fail fast.
Prerequisites
- k6 version ≥ 0.45.0 installed (older versions lack the
http_req_failedmetric and the--thresholds-abortflag). - A test script that issues HTTP requests (e.g., a simple GET to an endpoint).
- Access to a terminal or CI environment where you can run k6.
- Optional: a time‑series backend such as InfluxDB/Grafana if you want to store detailed metrics for later analysis.
Procedure
- Create or edit your k6 script – add a
thresholdsblock that defines the two rules:
import http from 'k6/http';
import { check, sleep } from 'k6';
export const options = {
thresholds: {
// 95th percentile of request duration must be < 500 ms
'http_req_duration{type:http}': ['p(95)<500'],
// overall failed request rate must be < 1%
'http_req_failed': ['rate<0.01'],
},
};
export default function () {
const res = http.get('https://test-api.k6.io/public/crocodiles/1/');
check(res, {
'status is 200': (r) => r.status === 200,
});
sleep(1);
}
- Run the test locally or in CI:
# Run from the directory containing script.js
k6 run script.js
- Observe the threshold evaluation – k6 prints a
thresholdssection at the end of the run:
█ http_req_duration{type:http}......: avg=120ms min=45ms med=90ms p(95)=480ms p(99)=620ms
█ http_req_failed................: 0.00% ✓ 0 out of 5000
█ thresholds....................: OK
If any rule fails, the corresponding line will show FAIL and the overall thresholds block will be marked FAIL.
Expected checks
- Textual output: look for the
thresholdsblock; each rule should displayOKorFAIL. - Process exit code: after the run, execute
echo $?. A value of0indicates all thresholds passed; any non‑zero value indicates at least one failure. - Optional JSON summary: run
k6 run --summary-export=summary.json script.jsand inspectsummary.jsonfor"thresholds":[{"ok":true},{"ok":false},...].
Recovery options
When a threshold fails:
- Inspect detailed metrics – export raw samples for post‑mortem:
k6 run --out json=results.json script.js
# results.json contains every sample; you can filter for high latency or errors.
- Adjust load pattern – reduce the number of virtual users (VUs) or duration to see if the system can meet the SLA under lighter load.
- Increase system capacity – scale the backend, add caching, or tune timeouts.
- Re‑evaluate the SLA – if the system cannot meet the target after optimisation, consider whether the latency bound is realistic given the architecture.
Limitations and practical verification
- Thresholds are evaluated only after the test finishes unless you use the
--thresholds-abortflag (available in k6 ≥ 0.45.0). Early failures will not stop the test automatically. - Omitting the
{type:http}selector onhttp_req_durationcauses the rule to match no samples, leading to a silent pass. Always include the selector when you want to measure HTTP request latency. - To verify that the threshold logic works as intended, you can deliberately violate a rule (e.g., change the URL to a non‑existent endpoint to generate errors) and confirm that the exit code becomes non‑zero and the
thresholdsblock showsFAIL.
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.