skip to content

HTML Dashboard

The HTML report JMeter builds from a JTL: how you ask for it, what it puts on screen, and how it computes the percentiles it shows. A staple of pipeline and reporting interviews.

on this pageshow

explore

questions

15

Which JMeter command-line flags produce the HTML dashboard at the end of a non-GUI run?

level: juniorimportance: must knowfreq 76%

answer

  1. Two flags added to the non-GUI command
  2. One asks for it, one names a folder
  3. Long names mention report at end
  4. It refuses without the results file

basics

~10 s

Two flags: -e asks JMeter to build the dashboard once the run ends, and -o names the folder it is written to. Both sit next to -l, which JMeter demands before it accepts -e.

solid answer

~50 s

A non-GUI run that ends in a dashboard looks like `jmeter -n -t nightly.jmx -l results.jtl -e -o dashboard`. `-e` (long form `--reportatendofloadtests`) takes no argument; it tells JMeter to run the report generator after every engine has stopped. `-o` (`--reportoutputfolder`) takes the destination folder, and it wins over the exporter's own `output_dir` property; with no `-o` at all the HTML pages land in `<JMETER_HOME>/bin/report-output` while `statistics.json` lands in `report-output` under the directory you ran the command from. `-e` is accepted only together with `-l`: without it JMeter prints `Option -e requires -l option` followed by the usage block and never starts the test, because the dashboard is built by reading back the file `-l` writes. Passing `-o` on its own is legal and silently produces nothing: JMeter validates the folder, runs the test and generates no report. A finished folder holds `index.html`, `content/`, `sbadmin2-1.0.7/` and `statistics.json`.

code

bash · 8 lines
bash
# generate the dashboard when the run finishes
jmeter -n -t nightly.jmx -l results/nightly.jtl -e -o results/dashboard

# legal, runs the whole test, and writes no report at all
jmeter -n -t nightly.jmx -l results/nightly.jtl -o results/dashboard

# rejected before the test starts: Option -e requires -l option
jmeter -n -t nightly.jmx -e -o results/dashboard

go deeper

for a junior

Memorise the working line: -n -t plan.jmx -l results.jtl -e -o folder. Be able to say which of those two extra flags asks for the report and which one names the folder.

for a middle

Explain why -e is refused without -l: the generator reads back the file the -l result collector writes. Know that -o alone silently produces nothing.

for a senior

Know that generation runs in the same JVM after the last engine stops, that it re-reads the whole JTL, and that a generation failure is only logged, never fatal.

for a principal

Decide where report settings and output paths live for a fleet of jobs, so that a dashboard's location and shape are a property of the job definition rather than of whichever machine ran it.

## The command line, flag by flag The canonical form shipped in JMeter's own manual is one line: ``` jmeter -n -t nightly.jmx -l results.jtl -e -o dashboard ``` | Flag | Long form | Argument | What it does | |---|---|---|---| | `-n` | `--nongui` | none | run without the GUI | | `-t` | `--testfile` | the `.jmx` | the plan to run | | `-l` | `--logfile` | the JTL | where samples are written | | `-e` | `--reportatendofloadtests` | none | build the dashboard when the run ends | | `-o` | `--reportoutputfolder` | a folder | where the dashboard is written | Only the last two belong to the report generator. The other three are the ordinary non-GUI run, and `-e` is bolted onto it. ## Why -l is not optional JMeter checks the pair before anything starts. If `-e` is present and `-l` is not, it raises an illegal-usage error, prints `Option -e requires -l option` with the whole usage block, and returns without running the plan. The reason is mechanical rather than stylistic: `-e` attaches a report generator to the very `ResultCollector` that `-l` creates, and the generator's input is that file. No `-l`, no file, nothing to read. The same wiring explains a second rule that surprises people: with `-e`, the file named by `-l` must not already exist with content in it. JMeter refuses at startup with `Results file:<path> is not empty` rather than appending a second run's samples to yesterday's numbers. ## Where the output folder comes from `-o` does not reach the exporters directly. JMeter resolves the path, checks that it is safe to write to, and sets the internal property `jmeter.reportgenerator.outputdir` to its absolute path. Both shipped exporters — `HtmlTemplateExporter` for the HTML pages and `JsonExporter` for `statistics.json` — read their own `output_dir` property first and then let that global value override it. Two consequences: - `-o` beats `jmeter.reportgenerator.exporter.html.property.output_dir`, whatever the property file says; - with no `-o` anywhere the two exporters part company: the HTML pages fall back to the compiled default and land in `report-output` under JMeter's `bin` directory, while `statistics.json` follows the relative `output_dir=report-output` the shipped `reportgenerator.properties` sets for the JSON exporter and lands in `report-output` under whatever directory you ran the command from. Passing `-o` overrides both and puts them back together, which is another reason not to rely on the default on a build agent. ## The trap: -o without -e `-o` is not a request for a report. It is only a destination. A command such as `jmeter -n -t nightly.jmx -l results.jtl -o dashboard` is completely valid: JMeter validates the folder, runs the whole test, writes the JTL, and produces no dashboard at all. Nothing warns you. This is the single most common way a pipeline ends up with an empty artefact directory, and the fix is one character. ## When the report is actually built Generation happens after the test, in the same JVM, from a listener that fires when the last engine has stopped. The log shows `Generating Dashboard` and then `Dashboard generated`. Two operational details follow: 1. The work is done by re-reading the JTL from disk, so a very large results file costs real time and I/O at the end of the run. 2. If generation throws, the exception is caught, printed as `Error generating the report: ...` and logged — the JMeter process does not stop or change what it already did. A missing dashboard is therefore easy to overlook if nobody reads stderr. ## What the folder contains A generated dashboard is a static site: `index.html`, a `content/` directory holding the JSON data files and the pages, a bundled `sbadmin2-1.0.7/` theme, and `statistics.json` written by the JSON exporter. It is copied from the templates in `bin/report-template`, which you can point elsewhere with `jmeter.reportgenerator.exporter.html.property.template_dir`. Nothing in it needs a web server; opening `index.html` from disk is enough.

  • What does JMeter do if you pass -o but forget -e?
    It accepts the command, validates that the folder can be written to, runs the whole test and writes the JTL, then exits without generating anything. `-o` only names a destination; `-e` is the request. There is no warning, so the failure shows up as an empty artefact folder later.
  • Where does the dashboard go if you omit -o?
    Into two places, and that is the surprise. The HTML pages take the HTML exporter's compiled default and land in `report-output` under JMeter's `bin` directory, while `statistics.json` follows the relative `output_dir=report-output` that the shipped properties file sets for the JSON exporter and lands in `report-output` under your working directory. When `-o` is given, JMeter sets `jmeter.reportgenerator.outputdir` to the absolute path and that value overrides both, so the flag always wins over the property file.

saying these in an interview costs you the question

  • Thinks every non-GUI run writes a dashboard automatically
  • Passes -o alone and expects a report
  • Believes -e can work without a results file
  • Confuses -e with -g, which reads an existing file
  • Assumes the report is written beside the JTL
open as a page

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

level: juniorimportance: must knowfreq 68%

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.

open as a page

How do you build a JMeter HTML dashboard from last night's results file without re-running the test?

level: middleimportance: must knowfreq 66%

basics

~10 s

Run the report generator on its own with -g: jmeter -g last-night.jtl -o dashboard. The flag takes an existing results file, so no plan is loaded and no load is generated.

open as a page

Why does one JMeter results file give a different 90% Line in the HTML dashboard and in the Aggregate Report?

level: middleimportance: must knowfreq 58%

basics

~20 s

The two surfaces use different percentile estimators. JMeter's HTML dashboard uses the commons-math3 LEGACY type, which interpolates between neighbouring samples; the Aggregate Report listener returns an actually observed elapsed time. Set backend_metrics_percentile_estimator=R_3 to align them.

open as a page

In JMeter, which properties decide that reports show the 90th, 95th and 99th percentiles?

level: juniorimportance: should knowfreq 34%

basics

~20 s

The three properties aggregate_rpt_pct1, aggregate_rpt_pct2 and aggregate_rpt_pct3, defaulting to 90, 95 and 99. Each takes a float between 0 and 100, so 99.9 is valid, and they move the GUI listeners and the HTML dashboard together.

open as a page

A JMeter run aborts with "Cannot write to ... as folder is not empty". What happened?

level: middleimportance: should knowfreq 58%

basics

~20 s

The folder given to -o already contains files. JMeter checks the report destination before the run starts and refuses rather than mix a new dashboard into an old one. The -f flag clears it first.

open as a page

In JMeter's dashboard APDEX table, what do the T and F columns hold?

level: middleimportance: should knowfreq 52%

basics

~10 s

T holds jmeter.reportgenerator.apdex_satisfied_threshold, 500 ms by default; F holds apdex_tolerated_threshold, 1500 ms by default. Despite the headings, T is the satisfied bound and F the tolerated bound, both in milliseconds.

open as a page

A JMeter dashboard row shows Average 210 ms and 99th pct 8,900 ms — which samples fed each figure?

level: middleimportance: should knowfreq 61%

basics

~20 s

Average and the 99th pct column are computed from exactly the same list of elapsed times: every sample carrying that label inside the report's range, failures included, over the whole run with no time dimension.

open as a page

A 4-minute JMeter run's dashboard shows only four points per over-time graph. What do you change?

level: seniorimportance: should knowfreq 44%

basics

~10 s

Lower jmeter.reportgenerator.overall_granularity. It defaults to 60000 milliseconds, so every over-time graph gets one point per minute. Set it in user.properties, keep it above 1000, and regenerate the existing results file.

open as a page

Why do the per-label Transactions/s values in a JMeter dashboard not sum to the Total row?

level: seniorimportance: should knowfreq 38%

basics

~10 s

JMeter divides each row's sample count by that label's own span, from its first sample's start to its last sample's end. Rows therefore use different, overlapping denominators, so their rates are not additive.

open as a page

Why can a JMeter dashboard's 99th percentile miss a slow warm-up that its Max column still shows?

level: seniorimportance: should knowfreq 42%

basics

~20 s

The dashboard's percentile columns run over a sliding window of the most recent samples, sized by jmeter.reportgenerator.statistic_window (default 20,000 per row). Min, Max and Average are not windowed, so they still see the whole run.

open as a page

How would you pin JMeter's percentile settings so every injector and every generated report agrees?

level: principalimportance: should knowfreq 29%

basics

~10 s

Ship one properties file with every JMeter install carrying the estimator, the report window and the three percentile levels. All three are read at startup, and the JVM generating the report needs them too.

open as a page

Which JMeter property selects the HTML report's percentile estimator, and what values does it take?

level: middleimportance: nice to knowfreq 27%

basics

~10 s

The key is backend_metrics_percentile_estimator, with no jmeter.reportgenerator prefix. It accepts a commons-math3 Percentile.EstimationType constant name: LEGACY (the default) or R_1 through R_9. Nothing else parses.

open as a page

In a JMeter dashboard, how do you show only a few named transactions in the graphs?

level: seniorimportance: nice to knowfreq 34%

basics

~10 s

Set jmeter.reportgenerator.exporter.html.series_filter to a regular expression matching the series you want, ending it with (-success|-failure)?$ so the per-second graphs still match. An empty value, the default, filters nothing.

open as a page

In JMeter's HTML dashboard, what do the four columns of the Errors table show?

level: seniorimportance: nice to knowfreq 30%

basics

~20 s

The Errors table lists Type of error, Number of errors, % in errors and % in all samples, one row per distinct failure key — unlike the Statistics and APDEX tables it has no Total row. The key is normally the response code and message.

open as a page