Skip to main content

Load generator · open source

Stroppy

A database stress-testing CLI: one self-contained Go binary, no runtime to install.

Point it at a database and run TPC-B, TPC-C, TPC-H or TPC-DS, or your own SQL. It loads the data, runs the load and hands back one JSON report with every step timed. The same binary runs on a laptop, in CI and inside Stroppy Cloud.

  • One Go binary
  • TPC-B, TPC-C, TPC-H, TPC-DS
  • PostgreSQL, MySQL, YDB, Picodata
  • Apache-2.0

Install and run

A pre-built binary from GitHub Releases, the Docker image, or a build from source with Go 1.24.3 or newer. The first argument picks a built-in workload; -d picks the driver and -D overrides its options.
Terminal
docker pull ghcr.io/stroppy-io/stroppy:latest

stroppy run tpcc/tx -d pg \
-D url=postgres://user:password@host:5432/dbname

Workloads

The TPC suites are built in; a .sql file or an inline query runs the same way.
  • tpcc/tx and tpcb/tx: raw transactions, every SQL driver.
  • tpcc/procs and tpcb/procs: stored procedures, PostgreSQL and MySQL; one round trip per transaction.
  • tpch/tx: eight tables and the 22 queries; tpcds: 24 tables from a faithful dsdgen port and the 99 queries.
Terminal
stroppy run tpcc/tx --executor constant-vus \
--vus 10 --duration 60s
stroppy run tpcc/tx --scale-factor 10 --load-workers 8
stroppy run tpcds --scale-factor 1
stroppy run queries.sql
stroppy run "select 1"

Drivers and config

PostgreSQL, MySQL, YDB and Picodata, plus CSV and noop. Settings you repeat go into stroppy-config.json: typed run parameters under run, workload parameters under params. A flag beats the environment, which beats the file.
stroppy-config.json
{
"version": "1",
"script": "tpcc/tx",
"run": {
"executor": "constant-vus",
"vus": 10,
"duration": "60s"
},
"params": {"scaleFactor": 10, "loadWorkers": 8}
}

Reports and metrics

Every run can write one versioned JSON report: effective inputs, host, steps, metrics, bounded errors and workload results. Live metrics go out over OTLP.
  • tps counts successful logical transactions; a retry that succeeds counts once.
  • Human output and diagnostics stay on stderr, so stdout stays valid JSON.
Terminal
stroppy run tpcb/tx -d pg --report-format json
stroppy run tpcc/tx -d pg --report-file result.json

Your own workload

stroppy init lays out a Go workload against the authoring API; go test runs it without a database; stroppy run takes it like a built-in, with its own flags.
Terminal
stroppy init select1
go test ./...
stroppy run select1 \
-D url='postgres://user@localhost:5432/postgres' \
--iterations 5
stroppy run select1 --help

Client overhead

stroppy baseline measures how fast Stroppy itself goes on this machine, against the noop driver and a server that only speaks the wire, so a result is never the client’s ceiling. What that ceiling looks like against other clients:
Terminal
stroppy baseline --quick
stroppy baseline --tiers noop,wire
stroppy baseline --quick --json > baseline.json
go-tpc → StroppyTPC-C on OrioleDB, one hour, 1000 warehouses, 100 VUs, Stroppy 5.7.2. How we found it
× go-tpc
go-tpc → tpcc/procs: 6,399 transactions per second before, 15,791 after, 2.5 times as many.
v5 on k6 → v6Medians of five runs on one AMD EPYC Genoa VM. Big on the noop driver, small on a real database, which is how it should be. Why we dropped k6
× v5
TPC-B ceiling, 1 VU: 4,368 transactions per second before, 145,524 after, 33.3 times as many.
TPC-B ceiling, 24 VUs: 38,694 transactions per second before, 517,627 after, 13.4 times as many.
TPC-C on PostgreSQL, 1 VU: 202 transactions per second before, 290 after, 1.4 times as many.
TPC-C on PostgreSQL, 16 VUs: 2,892 transactions per second before, 3,368 after, 1.2 times as many.
Database → Stroppy ceilingSame VM, 16 VUs. Different workloads; the gap is the room the client leaves.
× PostgreSQL
PostgreSQL TPC-C → noop TPC-B: 3,368 transactions per second before, 500,772 after, 148.7 times as many.

The other tools