skip to content

In JMeter's HTML dashboard, what does each column of the Statistics table tell you?

level: juniorimportance: must knowfreq 68%

answer

  1. Fourteen columns under five group headings
  2. Counts first, then times, then rates
  3. Top row is Total, and it never sorts
  4. Network figures are per second, not totals

basics

~10 s

The Statistics table gives one row per sample label plus a Total row: Label, #Samples, FAIL, Error %, Average, Min, Max, Median, three percentile columns, Transactions/s, and Received and Sent KB/sec.

solid answer

~40 s

Each row aggregates every sample recorded under one label for the whole range the report covers, and a `Total` row at the top of the table aggregates the run. Fourteen columns sit under five group headings: **Requests** (`Label`), **Executions** (`#Samples`, `FAIL`, `Error %`), **Response Times (ms)** (`Average`, `Min`, `Max`, `Median` and three percentile columns headed `90th pct`, `95th pct`, `99th pct` by default), **Throughput** (`Transactions/s`) and **Network (KB/sec)** (`Received`, `Sent`). `#Samples` is a count and `FAIL` the number of those marked unsuccessful; `Error %` is `FAIL` over `#Samples` for that same row. The response-time columns are all in milliseconds and come from each sample's elapsed time. `Transactions/s`, `Received` and `Sent` are rates, not totals. The same fourteen values are written to `statistics.json` beside `index.html`.

code

json · 18 lines
json
{
  "JR-OK" : {
    "transaction" : "JR-OK",
    "sampleCount" : 252,
    "errorCount" : 0,
    "errorPct" : 0.0,
    "meanResTime" : 235.90079365079367,
    "medianResTime" : 232.0,
    "minResTime" : 101.0,
    "maxResTime" : 353.0,
    "pct1ResTime" : 337.0,
    "pct2ResTime" : 339.35,
    "pct3ResTime" : 353.0,
    "throughput" : 4.187089806430174,
    "receivedKBytesPerSec" : 0.0736011880036554,
    "sentKBytesPerSec" : 0.03271163911273573
  }
}

go deeper

for a junior

Be able to name the columns and say that a row is one label over the whole run. Knowing that Error % is FAIL divided by #Samples for that row is enough at this level.

for a middle

Explain the five group headings and which columns are counts, which are milliseconds and which are rates. Say where the same numbers land in statistics.json.

for a senior

Show that you know what the table leaves out: no time axis, no thread counts, no error detail, and a Total row that drops Transaction Controller samples.

for a principal

Decide what your teams quote from this table in a written result, and insist the report artefact is kept whole rather than screenshotted, so the columns can be re-read later.

The Statistics table is the panel most people mean when they say "the JMeter report". It is a plain HTML table generated by `StatisticsSummaryConsumer` into `index.html`, sortable by clicking a heading, and it is the only place in the dashboard where every metric for a label appears side by side. ## What one row is A row is **one sample label**, not one thread, one user or one interval. Every sample in the result file that carries that label is folded into the row, across the whole date range the report covers. If a Transaction Controller writes a parent sample, that parent gets a row of its own under its own name; a controller that wrapped zero samples is skipped entirely. The `Total` row is the run-wide aggregate, and it sits at the top of the table, in its own unsortable body, so sorting by any heading never moves it. It is built from the same samples **minus** any Transaction Controller results, so that the parents are not double-counted with their children. ## The five column groups The header has two rows: a group band, then the real column names. | Group | Columns | Meaning | |---|---|---| | Requests | `Label` | the sample label, or `Total` | | Executions | `#Samples`, `FAIL`, `Error %` | how many ran, how many were unsuccessful, and the second as a percentage of the first | | Response Times (ms) | `Average`, `Min`, `Max`, `Median`, `90th pct`, `95th pct`, `99th pct` | seven figures, all in milliseconds, all from the samples' elapsed time | | Throughput | `Transactions/s` | samples per second for that row | | Network (KB/sec) | `Received`, `Sent` | kilobytes per second in each direction | The three percentile headings are literally rendered from the percentile numbers in use, so a report configured differently shows different headings — read the heading, do not assume 90/95/99. ## Where the numbers come from - `#Samples` counts every sample under the label; `FAIL` counts those whose success flag is false, which includes a sampler that returned an error code **and** one that a failing assertion marked unsuccessful. - `Error %` is computed per row as `FAIL * 100 / #Samples`, so a row with 3 failures out of 3 samples reads `100.00%` however small the run. - `Average`, `Min`, `Max`, `Median` and the percentile columns all read the same elapsed-time value for each sample. Failed samples are **not** excluded from them. - `Min` and `Max` are printed as whole milliseconds; the other response-time columns and the three rate columns are printed to two decimal places. - `Transactions/s` is that row's sample count divided by the span between its own first and last sample, expressed per second. ## What the row does not carry - **No time axis.** The row is one aggregate over the whole reporting range, so a burst confined to a few seconds is not visible in it; the over-time graphs on the other dashboard pages carry that dimension, aggregated to one-minute ticks by default. - **No per-thread breakdown.** Nothing in the table tells you how many threads produced the samples; the Active Threads Over Time graph does. - **No error detail.** `FAIL` is a count only; the Errors table below it names the failures. ## Sorting, and the panel beside it The table ships sorted by `Label` ascending, and every heading is clickable, so ranking the run by `Error %` or by `99th pct` is one click rather than an export. The grey group band above the headings is deliberately not sortable — it is a spanning header, not a column. Directly above the Statistics table sit two smaller panels: the APDEX table on the left and the **Requests Summary** pie on the right. The pie shows only two slices, `PASS` and `FAIL`, and it leaves Transaction Controller results out of both — so its `FAIL` percentage and the `Total` row's `Error %` are computed over the same sample set and should agree. ## The same numbers, machine-readable Every dashboard run also writes `statistics.json` into the output folder, keyed by transaction name with a `Total` entry. Its fields map one-for-one onto the columns — `sampleCount`, `errorCount`, `errorPct`, `meanResTime`, `minResTime`, `maxResTime`, `medianResTime`, `pct1ResTime`, `pct2ResTime`, `pct3ResTime`, `throughput`, `receivedKBytesPerSec`, `sentKBytesPerSec` — which makes it, not the HTML, the thing to read from a script.

  • What makes JMeter put a number in the Statistics table's FAIL column?
    Any sample whose success flag is false: a sampler that returned an error status, one whose response was rejected by an assertion, or one that JMeter itself could not complete. The column is a count; Error % is that count over #Samples for the same row.
  • Where does a JMeter dashboard run put the same figures in machine-readable form?
    In statistics.json, written to the report output folder alongside index.html by the JSON exporter. It is a map keyed by transaction name, with a Total entry, and one object per label carrying sampleCount, errorPct, meanResTime, the three pctNResTime values, throughput and the two KB/sec fields.

saying these in an interview costs you the question

  • Treats Average as the only response-time column
  • Reads Transactions/s as a count rather than a rate
  • Assumes Error % counts only HTTP 5xx responses
  • Believes Received and Sent are byte totals
  • Expects one row per thread instead of per label