Thresholds

Thresholds are the pass/fail contract of a test, evaluated continuously during the run and finally at the end. Any failing threshold makes loadr run exit with code 99 (k6-compatible).

thresholds:
  http_req_duration:
    - "p(95)<400"                    # plain expression
    - threshold: "p(99.9)<1500"      # object form
      abort_on_fail: true            # stop the test the moment it fails...
      delay_abort_eval: 30s          # ...but not in the first 30s (warm-up)
  http_req_failed: [ "rate<0.01" ]
  checks: [ "rate>0.99" ]
  my_custom_counter: [ "count>1000" ]
  "http_req_duration{scenario:api}": [ "p(99)<250" ]   # tag-filtered

Expression syntax

<aggregation> <op> <bound> where op< <= > >= == !=.

AggregationApplies toMeaning
avg, min, max, medtrendstatistics in milliseconds
p(N)trendany percentile, e.g. p(95), p(99.9) (HDR-exact)
rateratepass fraction 0..1; on counters: events/second
countcountertotal
valuegaugelast value

Bounds accept durations for time metrics: p(95)<400ms, avg<1.5s.

Tag selectors

metric{tag:value,tag2:value2} aggregates only samples whose tags include all listed pairs. Useful tags: scenario, name (request name), method, status, group, check, plus anything from tags: blocks.

thresholds:
  "http_req_duration{name:checkout}": [ "p(95)<800" ]
  "checks{scenario:browse}": [ "rate>0.95" ]

Semantics worth knowing

  • A threshold over a metric with no samples passes (matching k6) — but loadr validate warns when the metric name is unknown.
  • abort_on_fail triggers a graceful stop (in-flight iterations finish, summary still produced, exit code 99).
  • In distributed runs thresholds are evaluated centrally on merged histograms, so p(99) is the true fleet-wide percentile.