In JMeter's dashboard APDEX table, what do the T and F columns hold?
answer
- Two millisecond bounds, one score
- Column letters do not match property names
- Middle band earns half credit
- Failures count in the denominator only
basics
~10 sT 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.
solid answer
~40 sThe APDEX panel has four columns: `Apdex`, `T (Toleration threshold)`, `F (Frustration threshold)` and `Label`. `T` is filled from `jmeter.reportgenerator.apdex_satisfied_threshold` (default `500`) and `F` from `jmeter.reportgenerator.apdex_tolerated_threshold` (default `1500`), both in milliseconds — so the heading wording and the property names do not line up, and the pair is best read as *the fast bound* and *the still-acceptable bound*. JMeter scores a label as `(satisfied + tolerated / 2) / total`: a **successful** sample at or under `T` counts one, a **successful** sample above `T` but at or under `F` counts a half, and everything else counts nothing. Failed samples never earn credit but do go into the denominator. `jmeter.reportgenerator.apdex_per_transaction` overrides the pair for named or regex-matched labels; the `Total` row always uses the global pair.
code
properties · 5 lines# user.properties
jmeter.reportgenerator.apdex_satisfied_threshold=800
jmeter.reportgenerator.apdex_tolerated_threshold=3000
jmeter.reportgenerator.apdex_per_transaction=checkout:1500|4000;\
search-\\d+:500|2000go deeper
Know that the APDEX panel shows one score per label between 0 and 1, and that the two millisecond numbers beside it are the bounds the score was computed against.
Explain the half-credit formula and name the two properties, including the fact that the T column carries the satisfied threshold and F the tolerated one.
Show you know failures inflate the denominator, so an APDEX drop can come from errors rather than slowness, and check Error % on the same label before concluding anything.
Own whether one global threshold pair or per-transaction bounds is the house rule, and make sure whatever a team quotes as an Apdex always travels with the T and F it was scored against.
The APDEX panel sits on the left of the dashboard's index page, beside the Requests Summary pie and directly under the Test and Report information block. It is small, four columns wide, and it is the one table in the report whose column headings actively mislead. ## The two properties behind the two columns `ApdexSummaryConsumer` emits the columns in this order: | Column heading | Filled from | Default | |---|---|---| | `Apdex` | the computed score, to three decimals | — | | `T (Toleration threshold)` | `jmeter.reportgenerator.apdex_satisfied_threshold` | `500` ms | | `F (Frustration threshold)` | `jmeter.reportgenerator.apdex_tolerated_threshold` | `1500` ms | | `Label` | the sample label, or `Total` | — | The mismatch is real and it is the thing people get wrong out loud: the column called **Toleration** carries the **satisfied** threshold, and the column called **Frustration** carries the **tolerated** threshold. Read them positionally — `T` is the smaller number, `F` the larger — and remember both are milliseconds, never seconds. ## How JMeter builds the score For each label the consumer keeps three counters and computes: ``` apdex = (satisfiedCount + toleratedCount / 2) / totalCount ``` The counters are filled per sample, in this order: 1. Every sample under the label increments `totalCount` — **including failed ones**. 2. Only if the sample's success flag is true is its elapsed time examined at all. 3. Elapsed time at or under `T` increments `satisfiedCount`; otherwise, elapsed time at or under `F` increments `toleratedCount`; anything slower increments neither. Two consequences follow directly. A failing run is punished twice — once in the Statistics table's `Error %`, and again here, because failures enlarge the denominator while contributing nothing to the numerator. And a label whose samples are all slower than `F` scores exactly `0.000` even though every one of them succeeded. Samples produced by an empty Transaction Controller are skipped before any of this, so a controller that wrapped nothing cannot drag a score down. ## Per-transaction thresholds One global pair rarely fits a plan that mixes a search box with a nightly export. `jmeter.reportgenerator.apdex_per_transaction` sets a pair per label: - the format is `name:satisfiedMs|toleratedMs`, entries separated by `;` - `name` may be a literal label or a regular expression, and it must match the **whole** label, not part of it - exactly one matching entry is applied, but which one is unspecified when several patterns match: the entries are held in a `HashMap`, so the winner is not necessarily the one written first — keep the patterns non-overlapping. A label matching nothing keeps the global pair. - a chunk missing its colon or its pipe is logged as an error and ignored, leaving that label on the defaults The `Total` row is deliberately exempt: it is computed with `null` as the sample name, which matches no pattern, so it always uses the global `T` and `F`. That means the `Total` Apdex and a per-transaction Apdex in the same table can be scored against different bounds. ## Reading the table - The table is sorted by the `Apdex` column ascending by default, so the worst-scoring labels are the ones at the top — below the `Total` row, which sits in its own unsortable body above them and never moves. - The score is printed to three decimals; `T` and `F` are rendered as durations. - A score alone tells you nothing without its `T` and `F`, which is exactly why JMeter prints all three on the same row — quote them together or not at all. The same two thresholds are reused elsewhere in the report: the **Synthetic Response Times Distribution** graph takes its satisfied and tolerated boundaries from these very properties, so changing them redraws that graph's buckets as well as re-scoring this table. It is the one place in the dashboard where an APDEX setting has a visible effect outside the APDEX panel.
- Why can a JMeter APDEX row read 0.000 when the Statistics table shows Error % of zero for the same label?Because every sample succeeded but every one was slower than F. Success only makes a sample eligible for credit; the elapsed time decides whether it earns a full mark, a half, or nothing. A whole label sitting above F scores zero with no errors at all.
- Which thresholds does the Total row of JMeter's APDEX table use?Always the global pair from apdex_satisfied_threshold and apdex_tolerated_threshold. The overall row is scored with no sample name, so no apdex_per_transaction pattern can match it, even if every individual label in the table has been overridden.
Marking a paper with half credit: an answer inside T scores a full mark, one between T and F scores a half, anything slower or wrong scores nothing — and the Apdex is the class average.
saying these in an interview costs you the question
- Says T is the tolerated threshold
- Thinks failed samples are left out of the Apdex
- Reads the two thresholds as seconds
- Assumes a failure scores half credit
- Expects per-transaction thresholds to apply to Total