cd /news/developer-tools/loadr-a-rust-load-testing-tool-that-… · home topics developer-tools article
[ARTICLE · art-44632] src=loadr.io ↗ pub= topic=developer-tools verified=true sentiment=↑ positive

Loadr – a Rust load-testing tool that began as a single Claude prompt

Loadr, a Rust-based load-testing tool that began as a single Claude prompt, launches with features combining k6, JMeter, Gatling, and Locust. The tool offers declarative YAML tests, embedded JavaScript, six protocols, a live web UI, and distributed execution with exact percentiles, all in a single binary.

read13 min views1 publishedJun 30, 2026

#

Find the

breaking point.

loadr brings together the best ideas from k6, JMeter, Gatling and Locust in one place: declarative YAML tests, embedded JavaScript, six protocols, plugins, a built-in live web UI, and distributed execution with mathematically exact percentiles. All in one binary.

  live-demo — 1 scenario(s), 8.1s

  checks........................: 100.00% — ✓ 752 ✗ 0
    ✓ status is 200 (376 / 376)
    ✓ under 200ms (376 / 376)

  http_req_duration.............: avg=4.96ms med=3.02ms p(95)=10.73ms p(99)=49.38ms
  http_req_tls_handshaking......: avg=0µs (connections reused per VU)
  http_req_waiting..............: avg=4.85ms med=2.90ms p(95)=10.57ms
  http_reqs.....................: 376 (46.66/s)
  iterations....................: 376 (46.66/s)
  vus...........................: value=5 min=4 max=5

  thresholds:
    ✓ http_req_duration: p(95)<500 (observed: 10.73)
    ✓ checks: rate>0.95 (observed: 1.00)
    ✓ http_req_failed: rate<0.01 (observed: 0.00)

Why loadr

Four tools' best ideas. One Rust binary. #

loadr draws, with thanks, on four projects that shaped load testing: k6's execution model, JMeter's request arsenal, Gatling's flow-control DSL and feeders, and Locust's behaviour model — brought together and reimplemented in Rust. See what we built on →

Honest load, honest numbers

Open-model arrival-rate executors keep the offered load constant even when your system slows down — saturation shows up as dropped_iterations

, not silently lower throughput (requests per second, RPS). Every latency is an HDR histogram: p(99.9)

is exact, never estimated, never averaged.

Tests you can code-review

Declarative YAML with a generated JSON Schema — your editor autocompletes it, loadr validate

lints it with line numbers and did-you-mean fixes, and the diff in your PR actually means something. Drop into JavaScript exactly where logic demands it.

A platform, not just a CLI

Built-in management web UI (think RabbitMQ for load tests), distributed controller/agent mode over mTLS gRPC, six metric exporters, WASM & native plugins, and importers that eat your existing .jmx

plans and k6 scripts.

See it in action

Real recordings. Real runs. No mockups. #

Every clip is the actual loadr

binary executing against a live server.

View all 22 demos →

The live web UI, mid-run

Live charts, threshold pills, run controls, editor and fleet view — a real browser session.

The quickstart 0:24

A distributed fleet, live 0:34

Everything, in the box

The exhaustive feature list #

If it's listed, it ships in the binary — and every item links to its documentation.

All 7 k6 executors

constant-vus

, ramping-vus

, constant-arrival-rate

, ramping-arrival-rate

, per-vu-iterations

, shared-iterations

, externally-controlled

— identical semantics, open and closed models.

Concurrent scenarios

Any number of named scenarios per test with independent executors, stages, start times, graceful stop and ramp-down — browsers, API clients and batch jobs in one run.

Thresholds as CI gates

p(95)<400

, rate>0.99

, any percentile, tag-filtered selectors, abort_on_fail

circuit breakers with warm-up delay. Exit code 99 on failure — k6-compatible.

CI-native: GitHub Action + JUnit

A first-party setup-loadr

/ run

action installs the CLI and runs your plan, and --junit

emits a JUnit report every CI test panel renders — GitHub, GitLab, Jenkins, CircleCI.

Checks + JMeter assertions

k6-style checks that never fail requests, and JMeter-style assertions that do: status, body contains/regex, JSONPath, XPath, duration, size, headers, JS expressions — with abort actions.

Correlation & extraction

JSONPath, regex capture groups, XPath 1.0, CSS selectors, boundary extractors and headers — extracted values flow into later requests as ${name}

and into JS.

Data-driven testing

CSV & JSON feeders with sequential, random or shuffle strategies (shared or per virtual user (VU), recycle or stop-at-EOF), inline rows, and secrets that never reach logs.

Flow control & weighted tasks

repeat

, while

, if

/else

and weighted / uniform / round-robin random

branches — Gatling's loops and switches and Locust's weighted-task model, in declarative YAML.

Throttling

A global request-rate ceiling (throttle: { requests_per_second }

) on top of any executor — Gatling's reachRps

, for staying under a known rate limit no matter how fast the target is.

Embedded JavaScript

QuickJS per VU with k6-style imports (k6/http

, check

, sleep

, metrics), setup()

/teardown()

, scenario functions, beforeRequest

/afterRequest

hooks, inline ${js: …}

— sandboxed with time & memory limits.

Timers & pacing

Constant, uniform-random and gaussian think time; constant-throughput pacing (the JMeter timer, done right); per-scenario and global defaults.

Phase-level HTTP timings

DNS, connect, TLS handshake, send, TTFB and receive measured per request on a hand-built hyper stack — plus exact wire-level byte counts. No averaged guesses.

Cookies, redirects, bodies

Automatic per-VU RFC 6265 cookie jars with manual override, redirect policies, JSON/form/multipart/file bodies, query params — everything interpolated.

TLS, mTLS, proxies, HTTP/2+

Custom CAs, client certificates, SNI override, insecure mode for staging, HTTP/HTTPS proxies (CONNECT), ALPN negotiation with version forcing — all rustls, no OpenSSL.

Environment overlays

One file, many targets: loadr run -e staging

deep-merges named overlays — gentler CI load, staging URLs, relaxed thresholds, without copy-paste.

6 metric exporters

JSON lines, CSV, Prometheus (scrape + remote-write), InfluxDB line protocol, OpenTelemetry OTLP (gRPC & HTTP), StatsD — plus a pre-built Grafana dashboard in the repo.

WASM + native plugins

Five plugin types (protocol, output, extractor, assertion, service) over two mechanisms: sandboxed WASM components with a WIT interface, and abi_stable native libraries. No rebuilds, ever.

Distributed by design

Controller + agents over gRPC with optional mTLS: load partitioning, synchronized starts, data-file shipping, heartbeats, reconnection, agent-loss policies — and central HDR merging.

Built-in web UI

Live dashboards over SSE, a test editor with one-click validation, run history, /stop/scale controls, agent fleet view, log tail — embedded in the binary, dark mode native.

JMeter & k6 importers

loadr convert plan.jmx

translates thread groups, samplers, timers, assertions, extractors and CSV configs; the k6 importer maps options, scenarios, checks and http calls — with clear warnings for the rest.

Reports & tooling

k6-style console summaries, JSON export, self-contained HTML reports (loadr report

), shell completions, JSON Schema output, structured logs, --quiet

/-v

spectrum.

Show me

From smoke test to fleet-scale in the same file #

name: checkout-under-load
defaults:
  http: { base_url: https://shop.example.com }

data:
  users: { type: csv, path: users.csv, mode: shared, on_eof: recycle }

scenarios:
  shoppers:
    executor: ramping-vus
    stages: [ { duration: 2m, target: 100 }, { duration: 5m, target: 100 } ]
    think_time: { type: uniform, min: 1s, max: 3s }
    flow:
      - request:
          url: /login
          method: POST
          body: { form: { user: "${data.users.username}", pass: "${data.users.password}" } }
          extract:
            - { type: css, name: csrf, expression: "input[name=csrf]", attribute: value }
          assert:
            - { type: status, equals: 200 }
      - request:
          method: POST
          url: /cart
          body: { form: { sku: W-1, csrf: "${csrf}" } }
          checks:
            - { type: status, equals: 201 }
            - { type: duration, name: fast checkout, max: 300ms }

thresholds:
  http_req_duration: [ "p(95)<400", "p(99.9)<1500" ]
  http_req_failed: [ { threshold: "rate<0.01", abort_on_fail: true } ]
  checks: [ "rate>0.99" ]

Protocols

Six protocols. Full metrics on every one. #

Every protocol reports DNS, connect, TLS, TTFB, duration, and bytes sent/received — and works with the same extract/assert/check blocks.

HTTP/1.1 + 2

- request:
    method: POST
    url: /orders
    body: { json: { sku: W-1, qty: 2 } }
    checks: [ { type: status, equals: 201 } ]

ALPN, prior-knowledge h2, keep-alive tuning, per-VU pools.

WebSocket

- request:
    url: wss://chat.example.com/ws
    ws:
      send: [ '{"type":"hello"}' ]
      receive_until: '"ack"'
      session_duration: 10s

Subprotocols, binary frames, message counters, session metrics.

gRPC

- request:
    url: grpc://svc:50051
    grpc:
      reflection: true        # or proto_files
      service: helloworld.Greeter
      method: SayHello
      message: { name: "vu-${vu}" }

Unary + all streaming shapes, in-process proto compile — no protoc.

GraphQL

- request:
    url: /graphql
    protocol: graphql
    graphql:
      query: "query($t:String!){ search(t:$t){ id } }"
      variables: { t: widget }

GraphQL error semantics, partial-error awareness, own metric family.

TCP

- request:
    url: tcp://gateway:7000
    socket:
      send_text: "PING\r\n"
      read_bytes: 64
    checks: [ { type: body_contains, value: PONG } ]

Exact byte accounting; regex/boundary extraction over raw payloads.

UDP

- request:
    url: udp://stats:8125
    socket:
      send_hex: "deadbeef 0102"
      read_timeout: 500ms

Datagram round trips with hex payloads and loss-aware timeouts.

Need MQTT, Kafka, or your in-house protocol? Write a protocol plugin — no fork, no rebuild.

Distributed

Most tools average percentiles across nodes. That number is wrong. #

If agent A's p99 is 100 ms and agent B's is 1000 ms, the fleet's true p99 is not 550 ms. loadr agents stream HDR histogram deltas every second; the controller merges the histograms — a lossless operation — and computes percentiles only after the merge. Thresholds evaluate centrally against fleet-wide truth.

  • ▸ VU counts and arrival rates partitioned exactly across agents — global ramps stay precise
  • ▸ Synchronized start barrier, heartbeats, jittered reconnection, agent-loss policies
  • ▸ Test definitions and CSV/proto/JS files shipped to agents automatically
  • ▸ One bidirectional gRPC stream per agent, plaintext or mTLS
  • ▸ Docker Compose stack and Helm chart in the repo: agents.replicas=10

and go

partition · merge · thresholds · UI

200 rps

200 rps

200 rps

Management UI

RabbitMQ-style management, for load tests #

Embedded in the binary. loadr run --ui

for a single run, or the full fleet console on the controller. Edit and validate tests in the browser, watch live percentiles, , stop, or turn the VU dial mid-run.

Test library & editor

Save, edit and validate YAML in the browser — diagnostics jump to the line.

Run history

Every run's full summary persisted: trends, checks, thresholds, pass/fail.

Fleet view

Agent health, active VUs, cores, labels, last heartbeat — at a glance.

Auth built in

HTTP Basic and bearer tokens; loopback-only by default. JSON API for everything.

How loadr compares

loadr next to k6, JMeter, Gatling & Locust #

All four are excellent, widely-loved tools that shaped this space — this is simply where loadr sits relative to them; pick whatever fits your team. Where a cell says Enterprise or cloud, the capability exists in that project's paid/hosted tier. See also what loadr is built on.

k6 JMeter Gatling Locust loadr
Test format JavaScript XML (GUI) Scala / Java / Kotlin DSL Python YAML + JS, JSON-Schema validated
Open-model load (arrival rate) plugin ✓ injection profiles custom shapes ✓ all 7 executors
Protocols built in HTTP, WS, gRPC many HTTP, WS, SSE, JMS HTTP (custom clients) HTTP/1.1+2, WS, gRPC + reflection, GraphQL, TCP, UDP
Assertions / extractors / timers checks ✓ full checks + s in Python ✓ JSONPath, XPath, CSS, regex, boundary; 3 timers + pacing
Flow control & feeders (Gatling-style) code controllers ✓ DSL in Python ✓ repeat/while/if/switch/foreach + feeders + throttle
Extensions without rebuilding — (xk6 recompile) jars — (Scala recompile) Python ✓ WASM (sandboxed) + native plugins
Distributed execution cloud RMI Enterprise ✓ master / worker ✓ built-in, gRPC + mTLS
Fleet-wide percentiles cloud averaged Enterprise approximate ✓ exact (HDR histogram merge)
Live management UI cloud Enterprise ✓ built-in ✓ embedded
Per-phase timings (DNS/TLS/TTFB) partial ✓ on every protocol
Runtime footprint Go binary JVM + tuning JVM Python runtime one Rust binary, distroless image
Migration path in ✓ imports .jmx and k6 scripts

Standing on shoulders

What loadr is built on #

loadr is a fresh Rust implementation — not a fork of anything — but it takes the best ideas from four tools that defined load testing, deliberately and with thanks.

k6

the modelThe execution model is k6's: the seven executors, open/closed load, the four metric types, thresholds with abortOnFail

and exit code 99, checks and groups — and an embedded-JS experience so close the API is import-compatible (import http from 'k6/http'

).

Apache JMeter

the arsenalJMeter shaped the request toolkit: response / duration / size / JSONPath / XPath assertions; regex, boundary, CSS and XPath extractors; constant / uniform / gaussian and constant-throughput timers; CSV data sets and cookie management. loadr convert

reads your .jmx

plans.

Gatling

the DSLGatling gave loadr its flow control — repeat

, while

, if

/else

and the random / uniform / round-robin switch

— plus feeder strategies (sequential / random / shuffle), JSON feeders, and the request-rate throttle

.

Locust

the behaviour modelLocust's weighted-task model — users picking @task(weight)

actions at random — is exactly loadr's weighted random

step. Its clean real-time UI inspired loadr's management UI, and its master/worker model informed the controller/agent design.

The combination is the point: k6's model and JMeter's arsenal and Gatling's DSL and Locust's behaviour model — in one binary, with correct distributed percentiles, a plugin system and six protocols, rarely found together in a single tool. Full credits →

Trademarks and project names belong to their respective owners. loadr is independent and not affiliated with or endorsed by k6/Grafana Labs, the Apache Software Foundation, Gatling Corp, or the Locust project.

Roadmap

What's coming #

loadr already covers the core of k6, JMeter, Gatling and Locust. Here's where it's headed next — shaped by what those tools and their plugin ecosystems do that loadr doesn't yet. No dates, just direction; priorities shift with feedback.

Just shipped: SQL load testing (PostgreSQL & MySQL), the time-series HTML report, JMESPath & fused check-chains, and the in-UI failure & error breakdown.

Next up

  • Scriptable protocol clients in JS

Drive WebSocket and gRPC from JavaScript, plushttp.batch

and an async event loop / timers. - Server-side resource monitoring

Correlate CPU / memory / disk / network of the system-under-test with your load — JMeter's PerfMon, built in. - Programmable load shapes

Compute load per-tick in code, richer injection profiles (atOnceUsers

,nothingFor

, stepped ramps), and throughput-shaping profiles that adjust concurrency to hold a target RPS.

Planned

  • Proxy recorder loadr record

— capture real browser/API traffic and generate a test. - Manual pass/fail from JS

Mark a response failed/succeeded in script (Locustcatch_response

-style). - Messaging protocols

Kafka, MQTT, JMS and AMQP — likely as plugins on the existing plugin ABI. - Inter-VU coordination & auto-stop

Pass data between virtual users at runtime, and stop a run automatically when error-rate or latency guards trip.

Exploring

  • Managed outputs & dashboards

More exporters and hosted run-over-run trend comparison. - Distributed niceties --expect-workers

gating and custom controller↔agent messages. - Plugin registry

A browsable catalog of community WASM & native plugins.

Want something prioritised? It probably came from k6, JMeter, Gatling or Locust — tell us which workflow you're missing.

Install

Running in under a minute #

$ curl -sSL https://github.com/levantar-ai/loadr/releases/latest/download/loadr-x86_64-unknown-linux-gnu.tar.gz | tar xz
$ sudo mv loadr-*/loadr /usr/local/bin/
$ loadr version
bash
$ cargo install --git \
    https://github.com/levantar-ai/loadr loadr-cli

bash
$ loadr validate examples/01-quickstart.yaml   # line-numbered diagnostics, did-you-mean fixes
$ loadr run examples/01-quickstart.yaml        # exit 0 = thresholds passed, 99 = failed
$ loadr run --ui examples/02-ramping-load.yaml # live dashboard at http://127.0.0.1:6464
$ loadr report results.json -o report.html     # self-contained HTML report

27 runnable examples ship in the examples/

folder of every download — ramp, spike and soak tests, data-driven logins, WebSocket chat, gRPC streaming, GraphQL, Redis, SSE, headless-browser timing, raw sockets, environment overlays and a distributed fleet test. Browse all 34 →

The documentation is exhaustive. #

A getting-started path, the complete YAML reference, the full JS API, every protocol, distributed operations, plugin development with worked examples, and k6 and JMeter migration guides — everything you need to go from zero to a production load test.

── more in #developer-tools 4 stories · sorted by recency
── more on @loadr 3 stories trending now
sponsored brought to you by zahid.host 4,200+ EU-deployed projects
reading about agents? ship yours in a single git push.

Run your AI side-project on zahid.host

EU-based hosting, git-push deploys, automatic HTTPS, no cold starts. Free tier with a custom domain — perfect for shipping the agent you just read about.

$git push zahid main
Live at https://your-agent.zahid.host
Get free account → Pricing
from €0/mo · no card required
LIVE [news/loadr-a-rust-load-te…] indexed:0 read:13min 2026-06-30 ·