Diagnosing k6 Thresholds That Do Not Trigger
Learn why k6 thresholds may stay silent, how to verify metric collection and syntax, and what steps to take before escalating to the community.
09 Sept 2026, 00:23 UTC

Recognizable condition
You run a k6 test and the final output shows a thresholds section with all PASS results, but you expected at least one FAIL because a metric (e.g., response time) exceeded the limit you defined.
Cause / diagnostic table
| Symptom | Likely cause |
|---|---|
| Threshold never evaluates (no PASS/FAIL line) | Metric name in threshold does not match any collected metric |
| Threshold evaluates but always PASS despite high values | Wrong aggregation (e.g., using avg on a spiky metric) or threshold value too lax |
| Metric absent from output | Metric not enabled (missing --out, --summary-export, or not collected by default) |
| Threshold defined but ignored after test | Threshold object placed incorrectly (e.g., inside a function) or overridden later in script |
Ordered checks
- Verify metric collection
Run the test with
--vus 1 --duration 10sand look for the metric in themetricssection of the output. Example:k6 run --vus 1 --duration 10s script.jsIf the metric (e.g.,
http_req_duration) does not appear, it is not being collected. - Confirm threshold syntax
Check that the key in the
thresholdsobject exactly matches the metric name as printed (case‑sensitive).export const options = { thresholds: { 'http_req_duration': ['avg<200'] // note the quotes and exact name } }; - Inspect aggregation window
Some metrics (like
http_reqs) are counters; thresholds on raw counters may need a rate or sum. Ensure you are using the appropriate aggregation function (avg,p(95),max, etc.). - Review test execution logs
Add
--log-level debugto see if k6 reports "no samples" for the metric. Missing samples indicate the metric was not generated during the test.k6 run --vus 10 --duration 30s --log-level debug script.js - Ensure sufficient iterations
If the test ends before any iteration completes (e.g.,
--duration 1swith a 2‑second init), there may be no data to evaluate. Increase VUs or duration.
Fixes tied to findings
- Metric name mismatch – Rename the threshold key to match the exact metric string shown in the output.
- Wrong aggregation – Change the aggregation function; for latency spikes consider
p(95)<500instead ofavg<200. - Metric not collected – Enable the metric explicitly, e.g., add
--out json=results.jsonor ensure the relevanthttpcall is made in the script. - Threshold placed incorrectly – Move the
thresholdsobject to the top level of theoptionsexport. - Insufficient data – Raise
vusordurationto guarantee at least one sample.
Escalation criteria
If after completing the ordered checks the threshold still does not fire:
- Create a minimal reproducible script (see example below) that isolates the issue.
- Capture the full k6 output (
--log-level debug) and the script. - Open an issue in the k6 GitHub repository or ask in the k6 community forum, attaching the reproducer and logs.
Example: minimal verification script
Use this script to confirm that thresholds work in your environment:
import http from 'k6/http';
import { sleep } from 'k6';
export const options = {
thresholds: {
'http_req_duration': ['avg<200'] // expect average under 200ms
},
vus: 5,
duration: '30s'
};
export default function () {
const res = http.get('https://httpbin.org/delay/1');
sleep(1);
};
Run it:
k6 run verify_thresholds.js
Check the output for a section similar to:
█ thresholds
█ http_req_duration: avg<200 ................. FAIL
If you see PASS while the printed average is above 200 ms, the threshold is not evaluating correctly; revisit the checks above.
Limitations and practical verification
- Thresholds for counter‑type metrics (e.g.,
http_reqs) are evaluated only at test end; intermediate spikes will not trigger a fail. - Changing a threshold after a test run does not affect past results; you must re‑execute the test to see the impact.
- Overly strict thresholds on noisy metrics can cause false failures; consider adding a tolerance or using a longer aggregation window (e.g.,
p(95 over 10s)<500).
To verify that a fix worked, re‑run the test and confirm that the thresholds section now shows the expected PASS or FAIL matching the metric value printed in the summary.
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.