Benchmarks
Every number on this page comes from a committed evidence run with zero errors in every row, and every harness ships in the repository. Two instruments are used on purpose: our own matrix harness, and warp, MinIO's own benchmark tool, so the comparison cannot hinge on whose ruler was used. Read the caveats before quoting anything; they are part of the result.
How to read latency Throughput (MiB/s, ops/s) is "how much per second": higher is better. The p50 and p95
views are response times in milliseconds: p50 is the median request, p95 the slow tail, and lower is better. A Lockwell p50 at half of MinIO's means Lockwell answers twice as fast. The Advantage column already does this arithmetic for you, in the right direction, on every view. :::
The ledger
higher is better · advantage column = how many times better Lockwell is on this metric, in either direction
| Operation | Size | Clients | Lockwell | MinIO | Advantage |
|---|---|---|---|---|---|
| put | 4 KiB | 1 | 3.20 MiB/s | 0.56 MiB/s | 5.7x |
| put | 4 KiB | 16 | 17.4 MiB/s | 4.12 MiB/s | 4.2x |
| put | 4 KiB | 64 | 10.5 MiB/s | 9.09 MiB/s | 1.2x |
| put | 1 MiB | 1 | 155.4 MiB/s | 38.4 MiB/s | 4.0x |
| put | 1 MiB | 16 | 1,381 MiB/s | 188.8 MiB/s | 7.3x |
| put | 1 MiB | 64 | 1,622 MiB/s | 373.5 MiB/s | 4.3x |
| put | 64 MiB | 1 | 308.1 MiB/s | 266.0 MiB/s | 1.2x |
| put | 64 MiB | 16 | 1,593 MiB/s | 598.7 MiB/s | 2.7x |
| put | 64 MiB | 64 | 1,631 MiB/s | 400.9 MiB/s | 4.1x |
| get | 4 KiB | 1 | 11.3 MiB/s | 4.53 MiB/s | 2.5x |
| get | 4 KiB | 16 | 47.3 MiB/s | 45.7 MiB/s | 1.0x |
| get | 4 KiB | 64 | 78.5 MiB/s | 48.0 MiB/s | 1.6x |
| get | 1 MiB | 1 | 944.5 MiB/s | 256.9 MiB/s | 3.7x |
| get | 1 MiB | 16 | 8,598 MiB/s | 3,869 MiB/s | 2.2x |
| get | 1 MiB | 64 | 8,544 MiB/s | 5,203 MiB/s | 1.6x |
| get | 64 MiB | 1 | 2,858 MiB/s | 2,460 MiB/s | 1.2x |
| get | 64 MiB | 16 | 10,889 MiB/s | 4,733 MiB/s | 2.3x |
| get | 64 MiB | 64 | 5,410 MiB/s | 3,524 MiB/s | 1.5x |
| head | 4 KiB | 1 | 2,510 ops/s | 2,298 ops/s | 1.1x |
| head | 4 KiB | 16 | 11,512 ops/s | 13,179 ops/s | 0.9x behind |
| head | 4 KiB | 64 | 23,451 ops/s | 18,741 ops/s | 1.3x |
| head | 1 MiB | 1 | 3,123 ops/s | 1,007 ops/s | 3.1x |
| head | 1 MiB | 16 | 18,111 ops/s | 20,576 ops/s | 0.9x behind |
| head | 1 MiB | 64 | 42,878 ops/s | 43,716 ops/s | 1.0x behind |
| head | 64 MiB | 1 | 3,149 ops/s | 2,208 ops/s | 1.4x |
| head | 64 MiB | 16 | 17,290 ops/s | 20,865 ops/s | 0.8x behind |
| head | 64 MiB | 64 | 52,432 ops/s | 14,688 ops/s | 3.6x |
| list | 4 KiB | 1 | 2,001 ops/s | 524.3 ops/s | 3.8x |
| list | 4 KiB | 16 | 4,095 ops/s | 1,848 ops/s | 2.2x |
| list | 4 KiB | 64 | 2,737 ops/s | 464.9 ops/s | 5.9x |
| list | 1 MiB | 1 | 2,076 ops/s | 1,351 ops/s | 1.5x |
| list | 1 MiB | 16 | 5,114 ops/s | 2,044 ops/s | 2.5x |
| list | 1 MiB | 64 | 2,699 ops/s | 564.5 ops/s | 4.8x |
| list | 64 MiB | 1 | 2,067 ops/s | 1,687 ops/s | 1.2x |
| list | 64 MiB | 16 | 7,024 ops/s | 1,818 ops/s | 3.9x |
| list | 64 MiB | 64 | 3,661 ops/s | 503.9 ops/s | 7.3x |
| multipart-put | 64 MiB | 1 | 222.5 MiB/s | 232.6 MiB/s | 1.0x behind |
| multipart-put | 64 MiB | 16 | 985.1 MiB/s | 413.4 MiB/s | 2.4x |
| multipart-put | 64 MiB | 64 | 1,036 MiB/s | 532.9 MiB/s | 1.9x |
| multipart-copy | 64 MiB | 1 | 305.4 MiB/s | 205.4 MiB/s | 1.5x |
| multipart-copy | 64 MiB | 16 | 3,179 MiB/s | 325.3 MiB/s | 9.8x |
| multipart-copy | 64 MiB | 64 | 2,300 MiB/s | 338.9 MiB/s | 6.8x |
| mixed-rw | 4 KiB | 1 | 1,714 ops/s | 338.0 ops/s | 5.1x |
| mixed-rw | 4 KiB | 16 | 6,549 ops/s | 2,868 ops/s | 2.3x |
| mixed-rw | 4 KiB | 64 | 7,259 ops/s | 1,878 ops/s | 3.9x |
| mixed-rw | 1 MiB | 1 | 316.6 ops/s | 99.9 ops/s | 3.2x |
| mixed-rw | 1 MiB | 16 | 3,279 ops/s | 918.6 ops/s | 3.6x |
| mixed-rw | 1 MiB | 64 | 4,074 ops/s | 1,537 ops/s | 2.7x |
| mixed-rw | 64 MiB | 1 | 10.2 ops/s | 9.29 ops/s | 1.1x |
| mixed-rw | 64 MiB | 16 | 92.3 ops/s | 54.3 ops/s | 1.7x |
| mixed-rw | 64 MiB | 64 | 81.8 ops/s | 27.9 ops/s | 2.9x |
on-disk footprint for the identical write set: Lockwell 44.4 GiB vs MinIO 80.4 GiB (0.55x, lower is better)
2026-06-12 · Windows-11-10.0.26200-SP0 · zero errors required in every row (this run: 0) · reproduce: make bench
Caveats
These are part of the result, not footnotes to hide.
- Durability tier. The bench configuration runs Lockwell in its grouped-durability tier (the write-ahead log is fsynced every 10 ms, not per commit, matching Garage's model; a power loss can cost up to ~10 ms of acknowledged writes). MinIO runs its defaults, which sync per operation. Lockwell's default tier is strict per-commit sync; if your threat model requires it, benchmark that tier instead. This asymmetry flatters Lockwell most on small-object PUT, which is exactly where the warp gap is largest.
- One host. Server and client currently share a developer machine (Docker Desktop). Ratios and p50s are the signal; absolute numbers will differ on your hardware, which is why the harnesses ship. A neutral-hardware run is the plan of record, below.
- MinIO version. Each run pulls
minio/minio:latestat run time. Version-to-version variance is real, so cross-run comparisons of old tables mix that in. - CPU. Lockwell sustains the higher throughput while using more CPU than MinIO at peak. It trades compute for throughput and disk; if you are CPU-bound, weigh that.
- Small-object frontier. The honest losses live in the table too: HEAD and mixed-read p50 at 4 KiB under 16 and 64 clients run 1.1x to 1.5x behind MinIO. That path is transport-bound in both servers; we publish it rather than filter it.
- Storage. The random (incompressible) write set is the worst case for Lockwell's deduplication and compression and it still measures 0.54x MinIO's disk. On a compressible, duplicated dataset in an earlier validated run (2026-06-04), Lockwell stored 5.15 MiB where MinIO stored 1015.9 MiB.
Neutral hardware
Dev-machine numbers carry dev-machine noise. The standing plan is to run the same two harnesses on a fresh low-cost cloud box (the EUR 5 Hetzner class Lockwell is designed to fit), where nothing else is running, the exact specs are public, and anyone can rent the identical machine and check. scripts/bench-remote-hetzner.sh provisions the server with hcloud, runs make bench and make bench-warp, copies the evidence back, and destroys the box; the dataset selector above grows a new entry whenever such a run lands.
Reproduce
make bench # the full matrix harness (Lockwell, MinIO, Garage, SeaweedFS)
make bench-warp # MinIO's warp against Lockwell and MinIO on the same stackBoth write per-run evidence (transcripts, versions, raw outputs) under bench-results/; regenerate the dataset behind this page with node website/scripts/build-bench-data.mjs <matrix-dir> <warp-dir>. The methodology and the regression thresholds the release gates enforce live in docs/benchmark-baselines.md.