Reading JMeter's HTML Dashboard Report Correctly

A guide to JMeter's generated HTML dashboard report — which graphs matter, which are easy to misread, and how to compare two runs properly.

· By perf-test.com Editorial · AI-assisted
jmeterreportinganalysis

JMeter’s -e -o flag generates a self-contained HTML dashboard from a results file, with several graphs and tables. Knowing which ones to trust — and which are easy to misread — makes the difference between a report that informs a decision and one that just looks impressive.

APDEX: useful but needs configuring

The dashboard’s default APDEX (Application Performance Index) score uses generic satisfaction thresholds unless you configure them (via jmeter.reportgenerator.apdex_satisfied_threshold and ..._tolerated_threshold properties) to match your actual SLO. Left at defaults, an APDEX score doesn’t tell you anything about whether your specific latency target was met — it tells you about a generic threshold that may have nothing to do with your application.

Response Time Percentiles over the Average

The “Response Times Over Time” and percentile tables (90th, 95th, 99th) matter more than the headline average. A system whose average is fine but whose 99th percentile is 10x worse has a real tail-latency problem invisible in the average — this is true across nearly all performance testing, not specific to JMeter, but it’s an easy thing to skip past in a dashboard full of numbers.

Throughput graph: watch for the knee

The “Bytes Throughput Over Time” and “Hits Per Second” graphs show whether your test actually achieved steady load, or whether throughput degraded mid-run (often a sign the system under test started struggling, queuing requests, or hitting a resource limit). A throughput graph that ramps up cleanly then plateaus is healthy; one that ramps up and then visibly declines mid-test usually means you found a real capacity limit, not just variance.

Error rate isn’t always visually obvious

The dashboard’s error table lists failures by type, but a low percentage error rate can still represent a meaningful absolute number of failed requests at scale — 0.5% errors sounds small until it’s 5,000 failed checkouts in a 1-million-request test. Always look at absolute counts alongside percentages.

Comparing two runs side by side

JMeter’s dashboard doesn’t natively diff two runs against each other. For before/after comparisons (e.g. validating a fix), the practical approach is generating both reports separately and comparing the same specific metrics (p95 latency, error rate, max sustainable throughput) manually or via a small script reading both .jtl files — don’t rely on eyeballing two separately rendered HTML pages side by side for anything that needs to be precise.

What the report can’t tell you

The client-side report has no visibility into why the system was slow — that requires correlating with server-side metrics (CPU, GC pauses, database query time, connection pool exhaustion) collected separately, ideally with synchronized timestamps so you can overlay “JMeter saw a latency spike at 14:32:10” against “the database connection pool was exhausted at 14:32:08.”

Takeaway: the dashboard’s prettiest chart (APDEX) is the one most likely to be meaningless without configuration; the plainest-looking ones (percentile tables, raw error counts) are usually the ones worth trusting first.

Discussions coming soon.

Comments are powered by Giscus (GitHub Discussions). Enable them by configuring GISCUS in src/consts.ts — see giscus.app.