# Share an autocannon Report — Latency Percentiles Without a Terminal Paste

Canonical: https://commareports.com/share-autocannon-report
Published: 2026-09-08

> autocannon prints a table that turns into unreadable ASCII in Slack. Render it to HTML and publish it to Comma for a URL with the percentiles intact and a place to argue about them.

# Share an autocannon report

autocannon's terminal summary is well designed for a terminal and hostile to
every other destination. It is a space-aligned table with box-drawing borders,
so pasting it into Slack, a pull request, or a ticket produces one of two
results: a proportional-font mess, or a code fence that wraps on any window
narrower than the table and puts p99 under the "Avg" header.

The numbers survive; the ability to read them does not.

## Get machine-readable output

```bash
npx autocannon -c 100 -d 30 -j http://localhost:3000/api/orders > result.json
```

`-j` gives you the full result — every latency percentile, the throughput
histogram, the non-2xx count — instead of the rendered table.

## Render and publish

A small script turns that into something a person can read. The point is not
the chart library, it is that percentiles get a proper table and the tail is
visible:

```bash
npx autocannon -c 100 -d 30 -j http://localhost:3000/api/orders > result.json

node -e '
const r = require("./result.json");
const rows = Object.entries(r.latency)
  .filter(([k]) => k.startsWith("p") || k === "average")
  .map(([k, v]) => `<tr><td>${k}</td><td>${v} ms</td></tr>`).join("");
require("fs").writeFileSync("bench.html",
  `<h1>${r.url}</h1><p>${r.connections} connections · ${r.duration}s ·
   ${r.requests.average} req/s · ${r.non2xx} non-2xx</p>
   <table><tr><th>Percentile</th><th>Latency</th></tr>${rows}</table>`);
'

curl -fsS -X POST "https://commareports.com/api/v1/reports" \
  -H "Authorization: Bearer $COMMA_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d "$(jq -n --rawfile html bench.html \
        --arg t "Load — GET /api/orders" '{title: $t, html: $html}')"
```

Or skip the script entirely and drag the HTML into
[the app](https://commareports.com/).

## Lead with the tail

The mean is the number that gets quoted and the number that means least. A run
averaging 40 ms with a p99 of 1.8 s is a service that is fast for dashboards and
broken for users. Publish the distribution, and put `non2xx` next to it — a
throughput figure achieved while returning 503s is not a throughput figure.

## From CI

```bash
npx autocannon -c 100 -d 30 -j "$TARGET" > result.json
# …render bench.html as above…

curl -fsS -X PATCH "https://commareports.com/api/v1/reports/$REPORT_ID" \
  -H "Authorization: Bearer $COMMA_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d "$(jq -n --rawfile html bench.html \
        --arg t "Load — /api/orders @ $GITHUB_SHA" '{title: $t, html: $html}')"
```

PATCHing one report id per endpoint gives you a stable URL and a revision per
run — which is the cheapest performance-regression history you can have, and the
one most teams skip because the results were only ever in a job log that
expired.

## What review adds

- **Anchored threads** on the row somebody disputes — see
  [commenting on HTML](/comment-on-html).
- **Revisions**, so "we regressed on the connection-pool change" is checkable.
- **Access per report** — private, team, domain-gated or named reviewers. See
  the [sharing model](/docs/sharing).

## Limits

- **Entry HTML: 5 MB.** A rendered benchmark summary is kilobytes; this is not
  the limit you will meet.
- **60 requests/minute per token.**

## Try it

Comma is free — unlimited reports, unlimited commenters, unlimited revision
history.

**[Publish a benchmark →](https://commareports.com/)**

### Related

- [Share a k6 load test report](/share-k6-load-test-report) · [Share a Vegeta report](/share-vegeta-report)
- [Share an Artillery report](/share-artillery-report) · [Share a Clinic.js report](/share-clinicjs-report)
- [Share a benchmark report](/share-benchmark-report) · [Publish from CI](/docs/ci)
