# Share an Artillery Load Test Report

Canonical: https://commareports.com/share-artillery-report
Published: 2026-08-31

> Artillery v2 removed the built-in HTML reporter, so the JSON output has nowhere to go. Generate a page from it, publish to a URL, and discuss the p99 next to the p99.

# Share an Artillery load test report

Artillery's output is a summary table in a terminal and, if you asked for
it, a JSON file. The summary scrolls away. The JSON goes into an artifact
bucket.

And load test results have an unusually short useful life for an
unusually important reason: they exist to settle an argument — _is this
fast enough, and did the change help?_ — which means they need to be
readable by the people having the argument, most of whom were not in the
terminal.

## The v2 situation, stated plainly

Artillery **v1** had a built-in reporter:

```bash
artillery run -o out.json test.yml
artillery report out.json          # → out.json.html, one self-contained file
```

**v2 removed it.** The `report` command is gone, and the official path is
Artillery Cloud. If you are on v2 and want a local HTML artifact, you
generate it from the JSON:

```bash
artillery run --output report.json test.yml
```

`report.json` contains the aggregate and the intermediate buckets — enough
to render latency percentiles over time, error counts by response code,
and per-scenario breakdowns. A small template over it, or one of the
community converter packages, gets you a page.

That is genuinely more work than v1. It is also the honest state of the
tool, and worth knowing before you go looking for a flag that no longer
exists.

## Publish it

```bash
artillery run --output report.json test.yml || true
# …render report.json → report.html…

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 report.html \
        --arg title "Load test — $(git rev-parse --short HEAD)" \
        '{title: $title, html: $html}')"
```

One call, no assets, if the page is self-contained — which it should be,
since a load test report is mostly a few charts over a modest amount of
data. Use a [scoped token](/docs/api-tokens) (`reports:write`) from CI
secrets and `PATCH` a saved report id so one URL accumulates a revision
per run. See [publishing from CI](/ci).

The `|| true` matters if you use Artillery's threshold checks — a failed
SLO exits non-zero, and that is exactly the run worth publishing.

## Charts stay charts

If your rendered page uses a charting library, keep it self-contained
rather than CDN-linked. Scripts run inside a sandboxed iframe
(`allow-scripts`, no `allow-same-origin`), so an inlined chart library
boots and stays interactive — hover for the value at a timestamp, zoom
into the window where latency turned. See
[interactive HTML reports](/interactive-html-reports).

Anything the page tries to fetch from your internal network at view time
will not resolve; bake the data into the file.

## Argue about the p99 next to the p99

This is the whole reason to publish rather than paste:

- **"p99 is 1.2s"** — attached to the chart, someone can point out that
  the spike is the connection pool warming and the steady state is 300ms.
- **"the error rate is 2%"** — anchored to the step, someone notes those
  are all 429s from a rate limiter that isn't in production.
- **"this run isn't comparable"** — because the fixture data was smaller.
  Worth recording on the run itself, not in a reply three days later.

Select the number, leave a thread, and it stays anchored across revisions.
See [commenting on HTML](/comment-on-html).

## The comparison is the product

A single load test result is nearly meaningless. The useful artifact is
_this run versus the one before the change._

`PATCH`ing one report id gives you that for free: every run is a revision
at the same URL, and any two revisions can be diffed. A performance
regression conversation becomes "here are the two runs" rather than two
screenshots of two terminals.

For a nightly baseline, a
[routine](/features/routines/scheduled-html-reports) re-runs it on a cron
and posts the refreshed result as a new revision.

## Limits

- **Entry HTML: 5 MB** — generous unless you inline every raw sample;
  publish the aggregates and the intermediate buckets, not the full
  request log. Assets: 25 MB per file, 250 MB and 500 files total.
- **Scripts run, sandboxed** — no same-origin access.
- **60 requests/minute per token.**

## Try it

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

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

### Related

- [Share a k6 load test report](/share-k6-load-test-report) · [Share a JMeter report](/share-jmeter-report)
- [Share a Gatling report](/share-gatling-report) · [Share a Locust report](/share-locust-report)
- [Share a benchmark report](/share-benchmark-report) · [Publish from CI](/ci)
