Skip to content

JMeter APDEX, SLOs, and Percentiles

Map performance SLOs to JMeter dashboards: APDEX thresholds, p90/p95/p99 percentiles, error rates, reportgenerator properties, and CI performance gates.

Difficulty
intermediate
Guide type
concept
Estimated read time
12 min read
Last verified version
Verified JMeter 5.6

Performance SLOs, APDEX, and Percentiles with JMeter

Section titled “Performance SLOs, APDEX, and Percentiles with JMeter”

Load tests only help if you define what good looks like. This guide connects service-level objectives (SLOs) to JMeter’s HTML dashboard metrics: APDEX, percentiles, averages, error rate, and throughput, with definitions aligned to the glossary and report generator properties.

From the glossary: elapsed time is from just before sending the request to just after the last response byte is received. It does not include client-side rendering or browser JavaScript execution.

Time to the first response byte (glossary). Useful alongside elapsed for distinguishing slow servers from large payloads.

Time to establish the connection including SSL handshake where measured (glossary; available for certain samplers).

Requests per unit time over the full test window (glossary). High throughput with high errors is not success.

  • Median: 50th percentile (glossary).
  • Percentile (e.g. 90th): value below which that percentage of samples fall (glossary).

Averages hide long tails. SLOs usually use percentiles (p95/p99), not only mean.

Failed samples / samples. Failures include assertion failures and transport errors depending on how the sample is marked. Without assertions, HTTP 500 HTML pages may still count as successful samples.

APDEX (Application Performance Index) scores user satisfaction from response times against two thresholds:

  • Satisfied if response time ≤ T
  • Tolerating if T < time ≤ 4T (classic definition uses F = 4T; JMeter configures satisfied and tolerated thresholds explicitly)
  • Frustrated if above the tolerated threshold or failed (see how your report classifies errors)

JMeter’s dashboard includes an APDEX table “based on configurable values for tolerated and satisfied thresholds” (generating dashboard).

From report generator properties (also in properties reference):

PropertyDefault
jmeter.reportgenerator.apdex_satisfied_threshold500 ms
jmeter.reportgenerator.apdex_tolerated_threshold1500 ms

Override in user.properties (do not rely only on editing stock files long-term; copy overrides per best practices style).

jmeter.reportgenerator.apdex_per_transaction sets per-sample thresholds:

sample_name:satisfaction|tolerance;

Values in milliseconds; regex sample names supported as documented in the dashboard chapter.

The statistics table includes configurable percentiles. Related properties:

PropertyDefault percentile
aggregate_rpt_pct190
aggregate_rpt_pct295
aggregate_rpt_pct399

statistic_window controls sliding window size for percentile evaluation (default 20000); higher is more accurate but uses more memory (dashboard).

Example product SLO language:

99% of checkout requests succeed in under 750 ms over a rolling 30 days.

Load-test translation for a pre-prod experiment:

SLO pieceJMeter expression
SuccessError % for label Checkout ≤ 1% (or stricter)
Latencyp99 (or pct3) for Checkout ≤ 750 ms
Load shapeThreads/RPS that represent peak hour (document assumptions)
DurationSoak long enough for steady state (not only ramp)

Use Transaction Controllers with stable names so dashboard series match SLO names.

Weak targetStronger target
”Average under 1s""p95 under 1s and errors under 0.1%“
One global thresholdPer-transaction thresholds (login vs report download)
Spike onlySpike + soak
Open GUI eyeballingCLI report + CI gate
  1. Agree SLOs with product/SRE.
  2. Set apdex_satisfied_threshold / tolerated to match T and frustrated boundary you chose.
  3. Optionally set apdex_per_transaction for critical labels.
  4. Set aggregate_rpt_pct* to the percentiles in your SLO (e.g. 95/99).
  5. Filter noise with series_filter / sample filters so static assets do not dilute scores.
  6. Generate report: -e -o report/.

After the dashboard is generated, parse statistics (e.g. statistics.json paths for your version) for:

  • errorPct
  • Mean or percentile fields for critical transactions

See CI/CD load testing. Gates should fail the build when SLOs are violated in the test environment, with clear caveats that pre-prod ≠ prod.

PathUse
HTML dashboardAuditable artifact, APDEX table, error tables
Backend Listener → GrafanaLive during long tests (guide)

Define SLOs once; both paths should use the same sampler labels.

If the injector cannot keep up, latency percentiles look better than users experience. Best practices warn about coordinated omission when thread counts are wrong. Validate achieved throughput vs target (CO tool, Thread Calculator) before claiming SLO compliance from a test.

  1. SLO: Search API p95 ≤ 300 ms, errors ≤ 0.5%, at 50 RPS.
  2. Size threads from response time pilot (calculator).
  3. Label sampler Search.
  4. Assert HTTP 200 + JSON field present.
  5. Run CLI 15+ minutes steady.
  6. Report: check Search p95 and error %.
  7. APDEX satisfied threshold set near 300 ms if you want APDEX aligned to that SLO.

A satisfaction score derived from response times versus configured satisfied and tolerated thresholds, shown in the HTML dashboard APDEX table.

500 ms satisfied and 1500 ms tolerated unless you override reportgenerator properties.

Averages hide long tails. Users feel p95/p99. SLOs should specify percentiles and error rates.

Set aggregate_rpt_pct1, pct2, and pct3 (defaults 90, 95, 99) in report configuration properties.

Yes, via jmeter.reportgenerator.apdex_per_transaction with sample names or regex, as documented in the dashboard chapter.

Does a green APDEX mean production is safe?

Section titled “Does a green APDEX mean production is safe?”

No. It means samples in that test met thresholds under that load model and environment. Combine with capacity planning and production monitoring.

On this page