Apdex score: what it is and how to calculate it
7 min read
An Apdex score is a number between 0 and 1 that tells you what share of requests were fast enough for the people waiting on them. You choose a target time T: responses at or under T count in full, responses up to four times T count as half, and slower ones count as zero. A result of 1 means every request met the target, and 0 means every request was too slow.
| Zone | Response time | Weight in the score |
|---|---|---|
| Satisfied | up to T | 1 |
| Tolerating | above T, up to 4T | 0.5 |
| Frustrated | above 4T | 0 |
The facts below come from the tools’ own documentation and source code, checked on 19 October 2026.
How do you calculate an Apdex score?
Add the satisfied requests to half the tolerating ones and divide by all requests. The result always lands between 0 and 1.
Apdex(T) = (satisfied + tolerating / 2) / total
New Relic’s Apdex documentation works through an example with T set to 500 ms: out of 200 requests, 170 finished within 500 ms, 20 took between 500 ms and 2 seconds, and 10 failed or took longer. That gives (170 + 20 / 2) / 200 = 0.90 (checked on 19 October 2026).
A second example shows why the score is useful in a load test. Say a run sends 10,000 requests with T at 300 ms: 8,200 finish within 300 ms, 1,300 between 300 ms and 1.2 seconds, and 500 take longer. The Apdex is (8,200 + 650) / 10,000 = 0.885. The same run could easily report an average of 280 ms, which looks fine on its own and hides the 500 requests that took over a second.
Where does Apdex come from?
Apdex, short for Application Performance Index, is an open standard from a group of companies called the Apdex Alliance. Peter Sevcik of NetForecast founded the Alliance in 2004.
The Wikipedia article on Apdex cites Sevcik’s 2005 paper and gives the 4T rule. The Apdex Users Group now says the rules for the T and F thresholds “have become flexible” (checked on 19 October 2026), and tools use that freedom.
How do JMeter, Artillery and LoadFocus compute it?
All three start from T = 500 ms. They differ on where the tolerating zone ends and on what they do with failed requests, so the same run can give three slightly different numbers.
| Tool | Default T | Tolerating up to | Failed requests |
|---|---|---|---|
| JMeter HTML dashboard | 500 ms | 1,500 ms | counted as frustrated |
Artillery apdex plugin | 500 ms | 4T (2,000 ms) | only responses are scored |
| LoadFocus result page | 500 ms, fixed | 4T (2,000 ms) | scored on response time |
| New Relic APM | set per app | 4T | server errors are frustrated |
JMeter. The dashboard report has an APDEX table per transaction. Its defaults are jmeter.reportgenerator.apdex_satisfied_threshold=500 and apdex_tolerated_threshold=1500, so the tolerating zone ends at 3T unless you change it, and apdex_per_transaction sets different thresholds per sampler. In ApdexSummaryConsumer a failed sample adds to the total and never to the satisfied or tolerating counts, so every failure pulls the score down (checked on 19 October 2026).
Artillery. The apdex plugin works with the HTTP engine only and reports apdex.satisfied, apdex.tolerated and apdex.frustrated counters. Its source in artillery-plugin-apdex 1.24.0 scores each response on its total time against T and 4T, then prints the score with a label: excellent from 0.94, good from 0.85, fair from 0.70, poor from 0.49, unacceptable below that. A request that never gets a response is never scored (checked on 19 October 2026). Our Artillery review covers the tool itself.
LoadFocus, which publishes this site, shows the Apdex score in the Insights tab of a load test result, next to a response-time histogram. T is fixed at 500 ms and the tolerating zone ends at 2,000 ms; you cannot change T. Each sample is classified by its response time, with the satisfied, tolerating and frustrated shares printed beside the score.
How do you choose the T threshold?
Pick T from what users of that page or endpoint expect, and set it per transaction when your tool allows it. A single T for a whole application blurs a fast search endpoint and a slow report export into one number.
Some practical rules:
- Start from a real target. If you already have a latency objective such as “95% of checkout calls under 400 ms”, T = 400 ms keeps the Apdex and the objective telling the same story.
- Keep T the same between runs. An Apdex is only comparable with another Apdex measured at the same T. Report it as Apdex(0.4) or “Apdex at T = 400 ms” so nobody compares across thresholds.
- Match the tolerating zone too. JMeter’s default stops at 3T and the others at 4T. When you compare a JMeter report with another tool, set
apdex_tolerated_thresholdto four times T first. - Do not tune T to make a release pass. Moving T after a bad run changes the ruler, and the trend you were watching is gone.
What is a good Apdex score?
Artillery’s plugin calls 0.94 and above excellent and 0.85 to 0.94 good, and anything under 0.70 poor or worse. Those labels only mean something if T was chosen honestly.
An Apdex of 0.95 at T = 2 seconds can describe a slower service than 0.80 at T = 200 ms. When you set a release gate, write the threshold and the score together (“Apdex(0.5) of at least 0.9”) and check it next to a percentile limit, because the two catch different problems.
What does Apdex hide?
It squeezes the whole response-time distribution into three buckets, so it cannot tell you how slow the frustrated requests were. A request at 2.1 seconds and one at 30 seconds lower the score by exactly the same amount.
That is why it works best next to other numbers:
- Percentiles show how slow the slow requests are. Our guide to tail latency explains why the 99th percentile matters as soon as one page calls several services.
- Error rate catches failures your tool may not score. Artillery never scores requests that got no response, and New Relic counts server errors as frustrated, so read the error count separately.
- Sample size matters: New Relic notes that below about 100 requests per minute the score is unstable.
- Measurement bias applies too. A load generator that waits for slow responses sends fewer requests during slow periods, so the Apdex looks better than reality; see coordinated omission.
How do you use Apdex in a load test?
Treat it as a summary for people who will not read a histogram, and keep the pass/fail decision on explicit limits.
A workable routine:
- Set T per key transaction from your latency objective.
- Run the test and record the Apdex at that T, along with the 95th and 99th percentiles and the error rate.
- Compare the Apdex with the previous run at the same T. A drop from 0.93 to 0.86 is a clear signal even to someone outside the team.
- Fail the build on percentile and error limits, as described in our guide to load test pass/fail criteria, and report the Apdex alongside them.
FAQ
Is a higher Apdex score better? Yes. 1.0 means every request finished within T, and 0 means every request took longer than the tolerating limit or was counted as frustrated.
What is the default Apdex threshold in JMeter?
The HTML dashboard uses 500 ms for satisfied and 1,500 ms for tolerated. Change them with jmeter.reportgenerator.apdex_satisfied_threshold and apdex_tolerated_threshold.
Does Apdex include errors? It depends on the tool. JMeter counts failed samples as frustrated and New Relic treats server errors the same way, while Artillery’s plugin only scores requests that received a response.
Can I compare Apdex scores from two tools? Only when T, the tolerating limit and the handling of errors match. Otherwise compare the underlying percentiles and error rates instead.
Related reading
- Tail latency: what it is and how to measure it
- Load test pass/fail criteria: how to set them
- Coordinated omission: what it is and how to avoid it
- Throughput vs latency: how they interact under load
- Artillery load testing: a review of the Node.js tool
- SLO vs SLA: the difference, SLIs and error budgets
The technical claims in this article have not been independently reviewed.