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. 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 → credits 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 → /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, pause/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 /docs/plugins/overview.html — 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, pause, 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 credits . | 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 + pauses | 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 → /docs/credits.html 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, plus http.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 Locust catch 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 bash $ 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 no system deps: no protoc, no OpenSSL, no JVM, no node macOS Intel + Apple Silicon , Windows, Linux x86 64 + arm64 — every build, with SHA256 checksums and SLSA provenance: github.com/levantar-ai/loadr/releases 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 → /examples/ 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.