plow: Real-Time HTTP Benchmarking
plow -c 100 -d 30s http://localhost:8080/ benchmarks an endpoint with a live-updating latency histogram, and can cap throughput with --rate.
plow is a single Go binary that shows a real-time dashboard while it loads a service. For CI you run it headless with a duration or request count and read its summary to gate on latency and error rate.
What it does
plow sends requests using -c concurrent connections until it hits -n total requests or -d duration, drawing a live histogram of latency and status codes. --rate limits requests/sec for constant-throughput tests. It prints a final summary with percentiles and a status-code breakdown.
Common usage
# 100 connections for 30s
plow -c 100 -d 30s http://localhost:8080/
# fixed request count, capped rate, POST a body
plow -c 50 -n 20000 --rate 1000 \
-m POST -b '{"k":"v"}' -H 'Content-Type: application/json' \
http://localhost:8080/apiOptions
| Flag | What it does |
|---|---|
| -c, --concurrency N | Number of concurrent connections |
| -n, --requests N | Total requests to send (default unlimited) |
| -d, --duration T | Duration, e.g. 30s |
| --rate N | Cap requests per second |
| -m, --method <M> | HTTP method |
| -b, --body <data> | Request body |
| -H, --header <h> | Add a request header |
In CI
On a non-interactive runner the live dashboard is just extra log noise, so rely on the final summary; pipe it to a file and grep the Latencies percentile and status counts to gate. Set a -d or -n bound so the run terminates. Warm up with a short throwaway run first.
Common errors in CI
plow: command not found means download the release binary or go install github.com/six-ddc/plow@latest. dial tcp 127.0.0.1:8080: connect: connection refused means the server is not ready. If the terminal output looks garbled in CI logs, it is the TUI redraw codes; that is cosmetic, the final summary block is still printed.