gio bench
Load-test a running server: keep-alive connections for a fixed time, then throughput, latency percentiles and the X-Gio-Cache of the last response.
npx gio bench /posts/1pnpm exec gio bench /posts/1yarn gio bench /posts/1bunx gio bench /posts/1bash
gio bench <url-or-path> [--connections 32] [--duration 10] [--warmup 2]
gio bench --suite /,/posts/1 [--base <url>]Reference
| Option | Type | Default | Description |
|---|---|---|---|
<url-or-path> | string | - | The target: an absolute http or https URL, or a path starting with / requested from --base (default: the local server). Anything else (localhost:3000) is a usage error. Give either this or --suite. |
--connections <n> | number | 32 | Concurrent keep-alive connections, each sending one request after another. A whole number above 0. |
--duration <s> | number | 10 | Seconds to measure (per target with --suite). Must be above 0. |
--warmup <s> | number | 2 | Seconds of load before measuring; warmup requests count in no statistic. 0 skips it. |
--suite <paths> | string | - | Run several paths one after another and print a table. Paths are joined to --base. |
--base <url> | string | local server | Where paths go: an http or https URL. Without it, gio passes the local server's address, resolved like gio dev resolves it (GIO_PORT / PORT, .env files, gio.toml). |
-h, --help | boolean | - | Print the help and exit with 0. |
Behavior
- Every connection loops for warmup plus duration, sending
GETrequests and reading each body to the end. Requests per second is the measured request count divided by the duration. non-200counts measured responses with another status; they still count as requests.errorscounts failed requests (refused, reset). A connection gives up after three errors in a row.- Latency is per request, from sending to the last byte: p50, p90, p99 and max.
x-gio-cacheis the header of the last response, so a run against a cached page sayshitand an uncached onebypass: the numbers label themselves.
Examples
One target
text
$ npx gio bench /blog --duration 5
gio bench http://127.0.0.1:3000/blog
connections 32 duration 5s warmup 2s
requests/s 2077.80
requests 10389
non-200 0
errors 0
latency p50 14.81 ms
latency p90 24.27 ms
latency p99 37.07 ms
latency max 72.57 ms
bytes/s 5.35 MB/s
x-gio-cache hit; ttl=54 (last response)A suite
text
$ npx gio bench --suite /,/blog,/giojs-logo.svg --duration 5
gio bench suite against http://127.0.0.1:3000 (32 connections, 5s per target, 2s warmup)
target req/s p50 p90 p99 max non-200 errors bytes/s x-gio-cache (last)
/ 19.00 1314.36 ms 1527.28 ms 2395.88 ms 2395.88 ms 0 0 73.23 kB/s bypass
/blog 1679.20 16.73 ms 33.08 ms 60.03 ms 96.61 ms 0 0 4.33 MB/s hit; ttl=39
/giojs-logo.svg 832.40 47.62 ms 56.73 ms 75.28 ms 95.05 ms 0 0 525.24 kB/s staticThese runs used an unoptimized (debug) build of the server in a small container, against the starter app with a /blog page exporting revalidate = 60: they show the shape of the output and the gap between a cached page (hit) and a page rendered per request (bypass), not GioJS's speed. Measure with gio start and the published binary on hardware like production, and run the load generator on another machine for numbers you publish.
A remote server
bash
npx gio bench https://staging.example.com/ --connections 64 --duration 30Good to know
- Flags take their value as the next argument or after
=:--duration 5and--duration=5are the same. - A usage error - a bad flag or value, no target, a target that is neither a path nor an http(s) URL, both a target and
--suite- exits with code2before any request is sent, as everygiousage error does. A single-target run with no successful request exits with1(no successful requests to ... - is the server running?). A suite run exits0even when a target fails; read itserrorscolumn. - Every request is a plain anonymous
GET: no cookies, no request body. To load-test a form post or an authenticated page, use a dedicated tool. - It has no dependencies: plain
node:http/node:https.
Related
Version history
| Version | Changes |
|---|---|
v0.1.0-beta.8 | Paths and --suite go to the address the server listens on instead of http://localhost:3000. Usage errors exit with 2 instead of 1; flags also take --flag=value; a target that is not a path or an http(s) URL, and a fractional --connections, are usage errors. |
v0.1.0-beta.6 | Introduced. |