The Aggregate Report in JMeter: Turning Thousands of Samples into One Honest Table

The Aggregate Report in JMeter: Turning Thousands of Samples into One Honest Table

A deep, plain-English guide to the listener most testers open first, covering what every column really means, how the numbers are produced, why the TOTAL row and the average can mislead, and how to read the table like an experienced performance engineer.

Imagine a school that has just held an exam for two thousand students. The headmaster does not want to read two thousand individual answer sheets. She wants a summary: how many students sat the paper, what the typical mark was, how the weakest tenth did, how many failed outright. A good summary compresses a mountain of detail into a few numbers she can act on, and a bad summary hides the very students she most needs to worry about.

A JMeter test produces its own mountain: every single request from every virtual user becomes one recorded sample. The Aggregate Report is the summary table that compresses that mountain into one row per kind of request. It is simple to add and quick to read, which is exactly why it is so easy to misread. This guide explains it from zero knowledge, shows how it works inside, and teaches you what each number truly says and what it quietly hides.

1What the Aggregate Report Is and Why It Exists

We begin with the problem it solves, because the table only makes sense once the problem is clear.

The raw data problem

During a load test, JMeter records a sample for every request: when it started, how long it took, whether it worked, how many bytes moved. A ten-minute test with a few hundred users can easily produce hundreds of thousands of such records. No human can read them line by line, and looking at a handful of them tells you nothing about the whole.

The solution in one sentence

The Aggregate Report is a listener, an element that collects results, which groups all samples by their label, the name of the request, and calculates statistics for each group: how many there were, the average and median time, the slow tail, the error share and the rate at which they were completed.

Why it is so widely used

It answers the questions people ask first. Is it fast enough? Is anything failing? Which requests are the slowest? How much traffic did we actually push through? Because it shows these answers in a single compact table that updates as the test runs, it became the default window into a test for generations of testers.

Simple Analogy

Think of a restaurant manager at the end of an evening. She does not read every order ticket. She looks at one sheet showing, for each dish, how many were sold, how long the kitchen usually took, how long the slowest tenth took and how many were sent back. The Aggregate Report is that sheet for your application.

One
row per kind of request
Many
statistics per row
Live
table that updates during the run

2Core Concepts You Need First

A handful of terms appear throughout this guide, and learning them now makes everything easier.

Term 1

Sample

The record of one request: its label, start time, elapsed time, response code, success flag and size.

Term 2

Label

The name of a sampler. The report groups samples that share a label into one row.

Term 3

Listener

An element that receives samples and does something with them, such as showing a table, drawing a graph or writing a file.

Term 4

Elapsed Time

How long a request took from just before it was sent until its response was fully received, measured in milliseconds.

Term 5

Percentile

A value below which a stated share of samples fall. The ninety-fifth percentile is the time that ninety-five out of a hundred requests did not exceed.

Term 6

Throughput

How many requests were completed per unit of time. It measures how much work the system actually did.

Term 7

JTL File

The results log in which samples are saved, usually as comma-separated text. A listener can read one back for later analysis.

Term 8

Steady State

The part of a test when all users are active and the system has settled, which is where most conclusions should be drawn.

i
Remember

The Aggregate Report never changes what happens during a test. It only observes and summarises. All its numbers are derived from the samples that the samplers produce.

3Where It Fits Among the Result Listeners

JMeter offers many ways to look at results, and each answers a slightly different question.

Listener or ToolWhat It ShowsBest For
View Results TreeEvery request and response in detailDebugging a single user
Aggregate ReportPer-label statistics with median and percentilesQuick, readable summary of a run
Summary ReportPer-label statistics with standard deviation and average sizeLighter summary with spread information
Aggregate GraphThe aggregate figures drawn as a chartVisual comparison across requests
Simple Data WriterNothing on screen; writes samples to a fileLow-overhead recording during heavy load
Backend ListenerSummaries streamed to an external dashboardLive monitoring of long tests
HTML Dashboard ReportLinked pages with charts and tables built from a results fileFinal, shareable report
flowchart LR
  S[Samplers produce samples] --> L{Listeners}
  L --> A[Aggregate Report table]
  L --> T[View Results Tree]
  L --> W[Simple Data Writer to JTL file]
  W --> H[HTML Dashboard Report]
  W --> A2[Aggregate Report reading file later]
        
FIG 1 — Samples flow to several listeners; the Aggregate Report can read live data or a saved file
i
Reading the Picture

The Aggregate Report can work in real time or from a file written earlier. This second use, reading a saved file after a command-line run, is one of its most valuable roles.

4How It Works Inside

The table looks like magic until you see the simple bookkeeping behind it.

Samples arrive one by one

Each time a sampler finishes, JMeter creates a result object and offers it to every listener in scope. The Aggregate Report receives it and looks at its label. If the label is new, a new row is created; otherwise the sample is added to the existing row. At the same time a running total row is updated with every sample regardless of label.

What each row remembers

To compute counts and averages, a row needs only running sums. To compute the median and the percentile lines, it needs more: it must keep the individual elapsed times so it can find the value at a given position when they are sorted. This is why the Aggregate Report uses more memory than a simple counter, and why very long tests can make it heavy.

The table refreshes on a timer

Redrawing a table after every sample would swamp the machine, so the screen refreshes at intervals, while the underlying statistics are always up to date. In the graphical interface this redraw also costs processor time, one of the reasons real load tests should not rely on watching listeners.

sequenceDiagram
  participant V as Virtual User
  participant S as Sampler
  participant L as Aggregate Report
  participant R as Row for the label
  participant T as TOTAL row
  V->>S: Run request
  S-->>L: Finished sample with label and time
  L->>R: Find or create row, add sample
  L->>T: Add sample to overall totals
  L-->>L: Refresh screen at intervals
        
FIG 2 — How one finished sample updates the table
Simple Analogy

Picture a teacher marking papers and dropping each score into a pile for that subject. To report the average she only needs a running sum. To report the mark that separates the bottom tenth from the rest, she must keep every score so she can line them up. The Aggregate Report keeps the scores.

!
Common Misconception

Believing the Aggregate Report is free to leave enabled. Because it keeps individual times, it consumes memory proportional to the number of samples, and in the graphical interface its screen updates consume processor time too.

5Adding It and Reading the Screen

Setting it up takes a minute, and knowing the controls saves confusion later.

1

Add the listener

Right-click the test plan or a thread group, choose to add a listener and pick Aggregate Report. Placing it at the plan level collects results from every sampler.

2

Name it clearly

If you use several, give each a name that says what it covers, such as the whole test or one thread group.

3

Choose what to record

Checkboxes let the listener show only errors or only successes, which is useful when diagnosing failures separately from healthy traffic.

4

Optionally write to a file

A filename box lets the listener save raw samples to a results file. The same box can be used to load a saved file into the table.

5

Run and watch

Start the test and watch rows appear as each label produces its first sample.

6

Save the table

A button saves the displayed table as text, optionally with a header line, ready to open in a spreadsheet. A clear-all command resets the table between runs.

i
Hygiene Tip

Always clear the results before a new run. Old samples left in the table silently blend with new ones, and the averages then describe a mixture of two tests.

6The Columns Explained One by One

Every column answers one specific question, and knowing the question prevents misuse.

Column 1

Label

The name of the request the row describes. The last row, named TOTAL, combines everything.

Column 2

# Samples

How many times this request completed. It tells you how much evidence stands behind the other numbers in the row.

Column 3

Average

The arithmetic mean of elapsed times in milliseconds. Easy to understand but pulled upward by slow outliers.

Column 4

Median

The middle value: half the samples were faster and half slower. A truer picture of the typical request.

Column 5

90% Line

The time that ninety percent of samples did not exceed. One in ten requests was slower than this.

Column 6

95% Line

The time that ninety-five percent did not exceed. A common threshold in agreements about response time.

Column 7

99% Line

The time that ninety-nine percent did not exceed. It exposes the rare slow experiences that annoy real users.

Column 8

Min

The fastest sample. Often unrepresentative, since it may be a cached or trivial case.

Column 9

Max

The slowest sample. A single pause anywhere in the chain can set it, so treat it as a clue, not a verdict.

Column 10

Error %

The share of samples that failed, whether through a bad response code, a failed assertion or a timeout.

Column 11

Throughput

How many requests were completed per second, minute or hour, with the unit chosen automatically.

Column 12

Received and Sent KB/sec

The rate of data coming back from and going to the server, useful for spotting network limits and heavy pages.

i
Units

All response times in the table are in milliseconds. Throughput switches between per second, per minute and per hour depending on its size, so read the unit shown before comparing runs.

7Average, Median and Percentiles: Why One Number Is Never Enough

The three families of statistics describe different parts of the same crowd of samples.

The average hides the tail

Imagine ninety-five requests taking one second and five taking thirty seconds. The average comes to a little over two and a half seconds, a figure that matches neither the happy majority nor the miserable minority. The average blends them into a number nobody actually experienced.

The median shows the typical case

The median ignores how extreme the slow ones are and only asks what the middle sample looked like. In the example above it is one second, which truly describes what most users saw. Comparing the median with the average is a quick test of skew: when the average is much larger than the median, a slow tail is dragging it up.

Percentiles describe the experience of the unlucky

The ninety-fifth percentile asks how slow the unluckiest five percent were. In the example it is thirty seconds, exposing exactly what the average hid. Service agreements are often written in percentiles, because customers remember the slow experiences, not the average ones.

Simple Analogy

Think of the waiting time at a railway ticket window. The average might be four minutes, but if one passenger in twenty waits twenty minutes, those passengers tell their friends, and the station’s reputation follows them, not the average.

StatisticAnswers the QuestionWeakness
AverageWhat is the overall mean time?Distorted by slow outliers
MedianWhat did a typical request take?Says nothing about the slow tail
90th percentileHow slow were the unluckiest tenth?Misses rarer problems
95th percentileHow slow were the unluckiest twentieth?Needs enough samples to be stable
99th percentileHow slow were the unluckiest hundredth?Very sensitive with small sample counts
MaximumWhat was the single worst case?One-off events dominate it
“The average tells you where the crowd is. The percentiles tell you where the complaints are.”

8Percentile Lines and How to Configure Them

The ninety, ninety-five and ninety-nine lines are defaults, not laws of nature.

Where the values come from

The three percentile columns are controlled by settings in JMeter’s main property file. By changing those settings you can ask for different percentile lines, such as the ninety-eighth or the ninety-ninth and a half, so that the table matches the percentiles named in your own performance agreement. The change takes effect when JMeter is restarted, so decide before the test, not during it.

Match the table to the contract

If your organisation promises that ninety-five percent of requests will complete within two seconds, make sure the ninety-fifth line is present and treat it as the headline figure. Reporting a different percentile because it is the default invites arguments about whether the promise was kept.

How many samples a percentile needs

A high percentile is only meaningful when there are enough samples to populate its tail. The ninety-ninth percentile of two hundred samples is decided by the two slowest requests; a single hiccup changes it dramatically. As a rough habit, treat high percentiles from rows with only a few hundred samples as indicative rather than definitive, and repeat the test to see whether they hold.

Practice

Agree the Percentile First

Before testing, settle which percentile and which time limit define success, and configure the table to show it.

Practice

Report Several

Show the median and at least two percentiles so readers see both the typical and the unlucky experience.

Practice

Check Sample Counts

Read the sample count in every row before trusting a high percentile in that row.

Practice

Repeat the Run

Compare percentiles across repeated runs to learn how stable they are in your environment.

!
Common Mistake

Changing percentile settings after a run and then comparing the table with an older report that used the defaults. The columns carry the same headings but describe different percentiles.

9Error Percentage in Depth

A fast system that returns errors is not fast, so this column deserves as much attention as any time.

What counts as an error

A sample is counted as failed when its success flag is false. For web requests, that usually means a response code outside the successful range, a connection problem, a timeout, or a failed assertion that you added. Other protocols define failure in their own ways, such as a database error or an unexpected reply on a socket.

Why errors can be hidden

Without assertions, a server that returns an error page with a normal-looking code is counted as a success. The error column then shows zero even though every user saw a broken page. The reverse also happens: a strict assertion that is slightly wrong marks healthy responses as failures. The error column is only as honest as the checks behind it.

Fast failures flatter the averages

When a server is overloaded it often answers errors very quickly, because refusing a request is cheaper than serving it. Those fast failures pull the average and the median down, so a system in serious trouble can look faster than a healthy one. Always read response times together with the error share.

flowchart TD
  A[System under rising load] --> B{Overloaded?}
  B -- No --> C[Responses succeed, times grow gently]
  B -- Yes --> D[Server rejects requests quickly]
  D --> E[Error percentage rises]
  D --> F[Average time may fall]
  F --> G[Misleadingly good timing numbers]
  E --> H[Read time and errors together]
        
FIG 3 — Fast errors can make an overloaded system look quick
i
Diagnosis Tip

Use the listener’s option to show only errors, or only successes. Looking at the timing of successes separately gives a far truer view of how the system behaves for the users it is actually serving.

10Throughput in Depth and the Link to Users

Throughput is the most misunderstood column, because it depends on how you built the test as much as on the system.

What it measures

Throughput is the number of requests completed divided by the time over which they were completed, shown per second, per minute or per hour depending on size. It tells you how much work the system actually did during the test window.

It depends on the test design

In JMeter, virtual users wait for each response before sending the next request, and timers add pauses between actions. The rate at which requests are sent therefore depends on the number of users, the response times and the think times together. A slow system produces lower throughput simply because each user spends longer waiting.

A simple law connects them

For a steady test, the number of active users is roughly the throughput multiplied by the time each user spends per cycle, including response time and think time. If one hundred users each complete a cycle in five seconds, the system handles about twenty cycles per second. If response times double and think times stay fixed, throughput falls even though nothing is wrong with the load generator.

flowchart LR
  U[Number of users] --> T[Throughput]
  R[Response time] --> T
  K[Think time] --> T
  T --> S[Requests per second the system handled]
        
FIG 4 — Throughput follows from users, response time and think time together
Rising
throughput as users are added means headroom remains
Flat
throughput with growing times means saturation
Falling
throughput with errors means overload
!
Common Mistake

Treating throughput as a target the system must “reach”. It is a result of your design. To test a required rate, build the test to aim for that rate and check whether the system keeps up.

11Received and Sent Data Rates

Two small columns carry large clues about the network and about the weight of each page.

What they show

The received column shows how many kilobytes per second came back from the server, and the sent column shows how many went out. Both include headers as well as bodies. They are calculated over the same time window as throughput, so they rise and fall with it.

What they reveal

A sudden drop in received data with a rising error share often means the server has started returning short error messages instead of full pages. A very high received rate may mean the load generator’s own network link is becoming the limit, so response times start to include delays that belong to the generator. A high sent rate with large uploads can show where file or form submissions dominate the traffic.

Spotting heavy pages

Compare received rates across labels. A request whose row shows a rate far above the others is carrying a large response, a prime candidate for compression or caching work.

Spotting a saturated generator

If the received rate flattens at a suspiciously round number close to the generator’s network capacity while response times keep climbing, the generator, not the application, may be the bottleneck.

Confirming content is real

When errors are fast and small, the received data per request falls. A sudden fall in bytes per request is therefore a useful extra signal that responses have changed character.

i
Cross-Check

Compare the received rate with the network monitor on the generator. If both agree, the numbers are trustworthy; if they disagree, investigate before drawing conclusions.

12The TOTAL Row Trap

The last row looks like the verdict on the whole test, and that is exactly why it misleads.

What the TOTAL row is

The final row combines every sample from every label into one set of statistics. Its average is the mean of all requests together, and its percentiles are calculated across the whole mixed pool. It is convenient, and it is often quoted in summaries as if it described the system as a whole.

Why mixing hides the truth

Different requests have very different natures. A light request that checks status may take twenty milliseconds, while a report generation may take eight seconds. If the light request is called a hundred times more often, it dominates the pool, and the total average looks excellent even though the heavy request is painfully slow. The reverse also happens. The total row describes your particular mix of traffic, not a property of the application.

Percentiles of a mixture are fragile

The ninety-fifth percentile of a mixed pool can fall entirely within one kind of request. If most requests are quick, the slow ones might sit above the ninety-fifth line, invisible in that figure. A change in the traffic mix alone, with no change in the application, can move the total percentiles noticeably.

Simple Analogy

Imagine averaging the cooking time of every item a restaurant serves, from toast to slow-roasted lamb. A single figure emerges, but it describes neither the toast nor the lamb. Customers waiting for lamb get no comfort from the news that the overall average is eight minutes.

ANTI-PATTERN-01 Avoid
Problem

A report states that the system meets its target because the TOTAL row shows an acceptable average and ninety-fifth percentile.

Why It’s Harmful

Fast, frequent requests dominate the pool and hide slow, important ones. The headline passes while a key business action fails its target.

Correct Approach

Judge each business-critical request on its own row, against its own target, and treat the total as background context only.

13Labels, Transactions and Double Counting

Rows are only as meaningful as the labels that create them, and some elements add extra samples you may not expect.

Stable, descriptive labels

Each distinct sampler name becomes a row. Use names that describe the business action, such as opening the home page or adding an item to a basket, not technical details or changing values. A label that includes an identifier unique to each request produces a row per request and makes the table useless.

Transaction controllers and their two modes

A transaction controller groups several requests into one timed business step. Depending on its setting, it either generates a single parent sample and hides the children from listeners, or it produces an additional sample on top of the children, which remain visible. In the second mode the table contains both the individual requests and the combined step, and the total row counts them all.

Why this distorts totals

When children and the parent both appear, the total sample count and throughput include the same work twice, once as separate requests and once as the combined step. Averages in the total row then mix very short and much longer samples. Be clear which mode you chose, and read the total row accordingly.

SettingWhat Appears in the TableEffect on Totals
Parent sample generated, children hiddenOne row for the business stepCounts the step once; request-level detail is lost
Extra parent sample, children visibleRows for every request plus one for the stepWork is counted twice in the total
No transaction controllerOne row per request labelStraightforward; no business-level timing
i
Practical Choice

Use the parent-sample mode when you care about business-step timing, and a separate listener for request detail if needed. Add a naming prefix to the step so readers recognise it.

!
Common Mistake

Comparing the throughput of a run with transaction samples visible to a run without them. The same traffic produces different sample counts, so the throughput figures are not comparable.

14Ramp-Up, Warm-Up and Steady State

The table summarises the entire run, but the interesting behaviour lives in one part of it.

Three phases in every test

At the beginning, users start gradually during the ramp-up, and the system is lightly loaded, with empty caches and unprepared connections. In the middle comes the steady state, when all users are active and behaviour has settled. At the end the users finish and the load falls away. The Aggregate Report blends all three phases into one set of numbers.

Why blending misleads

Ramp-up samples were taken under light load, so they pull averages down and make the system look healthier than it is at full load. Warm-up samples may be unusually slow because nothing is cached yet, pulling the maximum and the high percentiles up. Ramp-down samples may be distorted by users stopping at different moments.

flowchart LR
  A[Ramp-up: light and growing load] --> B[Warm-up effects: cold caches, new connections]
  B --> C[Steady state: full load, stable behaviour]
  C --> D[Ramp-down: users finishing]
  C --> E[Best period for conclusions]
        
FIG 5 — The steady state is the part of the run that best describes the system under full load

What you can do

Option 1

Long Steady State

Design the test so the steady state is much longer than the ramp-up, which dilutes the effect of the early samples.

Option 2

Separate Warm-Up Run

Run a short warm-up before the measured test and discard its results.

Option 3

Filter by Time

Use a report generator that can limit analysis to a time window, so only the steady state is summarised. Check the settings your version supports.

Option 4

Note the Phases

At minimum, record when each phase began and ended, so readers understand what the numbers include.

!
Common Mistake

Running a five-minute test with a four-minute ramp-up and quoting the table. Almost every sample was taken while the load was still growing, so the table describes a system that was never fully loaded.

15Sample Size and Statistical Stability

A number from a handful of samples is a rumour; a number from many thousands is evidence.

Why counts matter

Every statistic in a row is an estimate drawn from that row’s samples. The more samples there are, the less a single odd value can move the result. A row with forty samples can swing wildly between runs, while a row with forty thousand barely moves.

Rare operations

Some actions happen far less often than others, such as a sign-in performed once per user or a rarely used report. Their rows have few samples, and their percentiles are correspondingly shaky. Do not draw firm conclusions from such rows without extending the test or isolating that action in its own scenario.

Samples in the RowHow to Treat the Numbers
Fewer than one hundredIndicative only; averages and medians are rough, percentiles unreliable
A few hundredAverage and median reasonable; ninety-ninth percentile still fragile
A few thousandMost statistics stable; repeat runs to confirm
Tens of thousands or moreStable estimates; differences between runs usually reflect real changes
i
Repeat to Learn the Noise

Run the same test three times and compare the rows. The spread between runs is the natural noise of your environment. A difference between two builds smaller than that noise proves nothing.

“A percentile without its sample count is a guess wearing a lab coat.”

16Saving, Loading and Exporting Results

Results are only useful if you can keep them, share them and look at them again later.

Write results to a file

The listener has a filename box. Entering a path there makes the listener write every sample it receives to that file, in the format and with the fields you choose through its configuration button. This produces the results log that other tools, including the dashboard generator, can read.

Read results from a file

The same box can load a previously saved file into the table. This is how you analyse a command-line run in the graphical interface afterwards: open the listener in a fresh plan, point it at the file and browse the rows. For very large files this loads many samples into memory, so allow enough memory or use the dashboard generator instead.

Save the table itself

A separate button saves the displayed table, with an option to include a header line. The result is a small text file with one line per label, ready to open in a spreadsheet, paste into a report or compare with a previous run.

1

Choose the fields to save

Use the configure button to include timing, label, response code, success flag and sizes, and avoid saving response bodies except where needed.

2

Name files with run details

Include the date, time and build number in filenames so no run overwrites another.

3

Keep the raw file

The table can be rebuilt from the results file, but the file cannot be rebuilt from the table. Always archive the raw log.

4

Export the table for reports

Save table data with a header and open it in a spreadsheet for comparison and charts.

!
Common Mistake

Archiving only the exported table and discarding the raw file. Later, when someone asks about a specific time window or request, the information to answer is gone.

17Memory, Performance and the GUI Question

A listener that helps you watch can also hurt the very test you are watching.

The cost of watching

In the graphical interface the Aggregate Report keeps individual times in memory and redraws its table regularly. Under heavy load with many users and a long duration, both costs grow. Garbage collection pauses lengthen, the processor spends time painting the screen instead of driving users, and the response times you record may include delays caused by the tool itself.

The command-line alternative

In non-GUI mode there is no screen to refresh, so the display cost disappears, but the listener’s memory cost remains if it stays in the plan. For large runs, the better design is a lightweight writer that saves samples to a file, with analysis done afterwards using the table or the dashboard generator.

SituationRecommended ApproachReason
Debugging with one or a few usersAggregate Report in the GUIOverhead is negligible and feedback is instant
Medium run in the GUIAggregate Report plus a results fileConvenient, but watch memory
Large or long runCommand line with a simple file writerLowest overhead and trustworthy timing
Analysing a finished large runDashboard generator or table loaded from fileAvoids rendering during the test
i
Memory Tip

If you must read a very large results file into the table, give JMeter a larger memory allowance first, and close other heavy listeners, so the analysis itself does not fail.

18A Practical Workflow: Run Headless, Analyse Afterwards

The healthiest habit separates measuring from looking.

flowchart LR
  A[Build and debug plan in GUI] --> B[Remove heavy listeners]
  B --> C[Run in command-line mode with file writer]
  C --> D[Raw results file]
  D --> E[Aggregate Report loaded from file]
  D --> F[HTML dashboard report]
  E --> G[Compare rows with targets]
  F --> G
  G --> H[Archive raw file, table export and notes]
        
FIG 6 — Measure headless, analyse afterwards
1

Prove the plan with a few users

Use the Aggregate Report and a detailed viewer to confirm each request works and each label looks right.

2

Strip the viewers

Disable or remove visual listeners and keep only a simple file writer for the real run.

3

Run from the command line

Write results to a uniquely named file and, if you like, ask for the dashboard at the end.

4

Load the file into the table

Open a clean plan with an Aggregate Report, point it at the results file and read the rows.

5

Judge per request

Compare each important row against its own target, using the steady-state period where possible.

6

Record and archive

Save the raw file, the exported table and a short note of settings and observations.

19Aggregate Report Versus Its Neighbours

Several tools show similar numbers, and knowing the differences avoids choosing the wrong one.

ToolStrengthsLimits
Aggregate ReportMedian and percentile lines in a compact table; can read and write filesNo standard deviation; keeps individual times in memory
Summary ReportIncludes standard deviation and average response size; lighter on memoryNo median or percentile columns
Aggregate GraphSame statistics drawn as charts for visual comparisonCharts are static snapshots, less convenient for reading exact values
HTML Dashboard ReportCharts over time, percentiles, error breakdown and a shareable formatBuilt after the run from a suitable results file
Community synthesis-style reportsCombine many columns, including spread and sizes, in one tableRequire a plugin and extra setup on every machine

Choosing among them

Use the Aggregate Report when you want a quick readable table with percentiles during development or when analysing a finished run. Use the Summary Report when you want a light listener and a measure of spread. Use the dashboard when the results must be shared, compared over time or presented with charts. Many teams use the table for fast checks and the dashboard for the official record.

i
Practical Note

The standard deviation in the summary report tells you how spread out the times are. A large standard deviation next to a modest average is another way to detect a slow tail without reading percentiles.

20Reading the Patterns: Healthy Versus Troubled Tables

Experienced engineers read the shape of the table, not just individual numbers.

What You SeeLikely MeaningWhat to Check Next
Median close to average, percentiles close tooConsistent, well-behaved responsesConfirm errors are near zero
Average far above medianA slow tail pulls the mean upLook at the ninety-ninth percentile and maximum
Very high maximum, normal percentilesRare one-off pausesCheck garbage collection and network events
Rising error percentage with falling averageOverload producing fast failuresLook at error types and server resources
Throughput flat while times growThe system has reached saturationFind the resource that is exhausted
One row far slower than the restA specific operation is the bottleneckTrace that request through the backend
Received rate unexpectedly lowResponses may be errors or emptyAdd or tighten assertions
Results differ widely between identical runsUnstable environment or too few samplesLengthen the run and repeat
Simple Analogy

Reading the table is like a doctor reading a set of vital signs together. A slightly raised pulse alone means little, but a raised pulse with a fever and low blood pressure tells a story. The numbers matter in combination.

!
Common Mistake

Focusing on a single column, usually the average, and ignoring the others. Every pattern in the table above needs at least two columns to recognise.

21Turning Numbers into Pass or Fail

A table informs; a decision needs agreed thresholds.

Agree targets before the test

Settle in advance which requests matter, which statistic judges each, and what limit means success. A typical rule reads: for each critical request, the ninety-fifth percentile must stay below a named time and the error share below a named percentage. Without prior agreement, every result becomes an argument.

Judge each request against its own target

A search might need to answer in one second, while a report may be allowed ten. Setting one limit for the whole table either blocks reasonable slow operations or lets important fast ones slip. Give each critical row its own limit.

Automate the verdict

For pipelines, a script can read the saved table or results file and compare the figures against the agreed limits, failing the stage when any is exceeded. Keep the limits in a version-controlled file so reviewers can see when and why they changed.

Threshold

Percentile Limit

A time that the chosen percentile must not exceed for each critical request.

Threshold

Error Limit

A maximum error percentage, often very small for important actions and zero for payments.

Threshold

Throughput Floor

A minimum rate the system must sustain, checked only when the test is designed to aim for that rate.

Threshold

Minimum Sample Count

A required number of samples per row, so verdicts are never based on a handful of requests.

i
Practical Note

Compare each run against a baseline run of the previous release as well as against absolute limits. A slow drift that stays within limits is still worth noticing early.

22Hidden Delay: Waiting Users and Missing Samples

A subtle effect of how JMeter users behave can make a struggling system look better than it is.

Users wait for answers

A JMeter virtual user sends a request and waits for the response before doing anything else. If the system stalls for twenty seconds, that user produces no samples during the stall. A real crowd, arriving on its own schedule, would have kept arriving, and many more people would have experienced the stall.

What this does to the table

During a stall, fewer samples are recorded, and only the few that were already waiting show the long delay. The percentile lines are then calculated from a pool in which the slow period is under-represented. The table can understate how bad the stall was for the people who would have arrived during it.

Ways to reduce the effect

Model arrival rates, not only users

Where real traffic arrives at a steady rate regardless of response time, use elements that control the rate of requests, so the test keeps arriving during a stall.

Watch the time-based charts

A chart of response time over time, and of requests per second over time, shows stalls clearly even when the summary table smooths them away.

Always inspect the maximum and the error column

Very large maxima, timeouts and rising errors are the visible fingerprints of a stall that the percentiles may hide.

!
Common Misconception

Believing the percentiles in the table fully describe what a real crowd would have experienced. They describe what your virtual users experienced, which is shaped by how they were told to wait.

23Behaviour in Distributed Tests

When several machines generate load, the table is built in a different place from where the samples are born.

Samples travel to the controller

In a distributed test, each worker runs its own threads and sends its samples back to the controller, where the listener summarises them. The sample counts in each row are the sum over all workers, and throughput describes the combined traffic. This is exactly what you want, but it comes with costs.

The controller can become the bottleneck

Receiving every sample from many workers takes processing and network capacity on the controller. A heavy listener on the controller, with its memory and screen updates, can slow the whole arrangement. For big distributed runs, let each worker write its own results file and merge the files afterwards, or use a lighter listener, and reserve rich analysis for after the test.

Clock and configuration differences

Samples carry time stamps from the machine that produced them. If worker clocks differ noticeably, time-based analysis such as throughput windows can be distorted. Keep worker clocks synchronised and confirm that every worker used identical settings, because a single misconfigured worker can quietly change a row’s numbers.

flowchart LR
  W1[Worker 1 samples] --> C[Controller]
  W2[Worker 2 samples] --> C
  W3[Worker 3 samples] --> C
  C --> A[Aggregate Report: combined rows]
  W1 -. optional .-> F1[Worker results file]
  W2 -. optional .-> F2[Worker results file]
  W3 -. optional .-> F3[Worker results file]
  F1 --> M[Merged file for later analysis]
  F2 --> M
  F3 --> M
        
FIG 7 — Combined live table on the controller, or merged files afterwards
!
Common Mistake

Leaving rich listeners on the controller of a large distributed test. The controller slows, results back up, and the table reflects the controller’s struggles rather than the application’s behaviour.

24Reading the Table Next to Server Metrics

The table shows symptoms as users saw them; the servers hold the causes.

When a row slows down

Open the server dashboards for the same period. Look for rising processor use, growing queues, exhausted connection pools, long database waits or garbage collection pauses on the services behind that request.

When errors rise

Read the error types in the results and match them with server logs. Time-outs point towards saturation, refused connections towards limits, and application errors towards defects.

When throughput flattens

Find the resource that stops growing. A flat line in database connections, threads or network use usually marks the limit that the test has discovered.

When results look too good

Check that the load generator is healthy and that responses are real. A saturated generator or a cache that answers every request can both produce suspiciously fast tables.

Make the comparison easy

Record the start and end time of each test, and align the clocks of the generator and the servers, so a spike in the table can be matched to events elsewhere. Use the same time zone in all notes. A table without a time reference is hard to connect with anything else.

i
Practical Note

Agree with the owners of each backend, before the test, which metrics they will capture. Discovering afterwards that nobody recorded the database side wastes the whole run.

25Security Considerations

Results look harmless, but they can carry more than numbers.

Labels can leak information

Sampler names are copied into results and tables. A label that includes an account name, an address or a token fragment spreads that detail into every report and chat message.

Raw files hold more than the table

A results file may contain request headers, cookies, response bodies and parameters, depending on what you chose to save. Treat it as sensitive data, restrict access and delete it according to policy.

Exports travel far

Saved tables are pasted into tickets, emails and slide decks. Check them before sharing for names of internal systems or other details that should stay inside the organisation.

Do not save more than you need

Saving response bodies for every sample multiplies both the storage and the risk. Save them only for failures and only while diagnosing.

Protect shared report folders

If results are published to a shared location, review who can read them. Performance numbers can reveal capacity limits that competitors or attackers would find useful.

!
Common Mistake

Posting a screenshot of the table into a public channel with real account names in the labels. Use stable, business-level labels so reports are safe to share.

26Design Patterns That Work

These patterns appear again and again in teams that read their results well.

Pattern

Measure Headless, Read Afterwards

Run load from the command line with a light writer, then open the table or dashboard on the saved file.

Pattern

Targets Per Request

Define success per business-critical request, with its own percentile and error limits.

Pattern

Stable Business Labels

Name samplers after business actions so rows are meaningful and safe to share.

Pattern

Steady-State Focus

Design long steady phases, record phase boundaries and judge results from the steady period.

Pattern

Baseline Comparison

Keep a reference run for each release and compare rows against it, not only against limits.

Pattern

Two Views of the Same Data

Use the table for quick checks and the dashboard for charts over time and the official record.

Simple Analogy

A good analyst is like a pilot reading several instruments before deciding on a landing. No single dial settles it, and the pilot knows which dials matter at which stage of the flight.

27More Anti-Patterns to Avoid

Besides the misleading total row, these mistakes look harmless and quietly spoil conclusions.

ANTI-PATTERN-02 Avoid
Problem

The team compares builds using only the average column.

Why It’s Harmful

A change that worsens the slow tail while slightly improving the average looks like progress. Users who meet the slow tail feel the opposite.

Correct Approach

Compare median and at least the ninety-fifth percentile, together with the error share and sample counts.

ANTI-PATTERN-03 Avoid
Problem

A large load test is run in the graphical interface with the Aggregate Report and several visual listeners enabled, so the team can watch it live.

Why It’s Harmful

Memory and processor use rise, pauses grow, and recorded timings include the tool’s own overhead. The test may even fail from memory exhaustion.

Correct Approach

Run headless with a file writer, watch server metrics live, and read the table from the saved file afterwards.

ANTI-PATTERN-04 Avoid
Problem

The table from a previous run is not cleared before starting the next one.

Why It’s Harmful

Old and new samples blend together. The rows describe a mixture of two tests, and nobody can say which numbers belong to which.

Correct Approach

Clear all results before each run, and write each run to its own uniquely named file.

ANTI-PATTERN-05 Avoid
Problem

A system is declared healthy because error percentage is zero, but no assertions check the content of responses.

Why It’s Harmful

Error pages with normal response codes count as successes. Users see broken pages while the table shows perfect health.

Correct Approach

Add assertions that verify meaningful content for every critical request, and check received data rates for sudden changes.

ANTI-PATTERN-06 Avoid
Problem

Two runs with different ramp-up lengths, transaction settings and traffic mixes are compared row by row as if they were identical tests.

Why It’s Harmful

Differences in the table come from the test design, not from the application, so conclusions about the build are wrong.

Correct Approach

Keep test design identical between compared runs, record every setting, and change only one thing at a time.

28Advantages, Disadvantages and Trade-offs

An honest look at benefits and costs shows when the table is the right tool.

Advantages

  • Compact, readable summary with median and percentile lines
  • Quick to add and understand, even for beginners
  • Works live during a run or on a saved results file
  • Exports easily to spreadsheets for comparison
  • Configurable percentile columns to match agreements
  • Shows errors, throughput and data rates in one place

Disadvantages / Trade-offs

  • Keeps individual times, so memory grows with sample count
  • Summarises the whole run, blending ramp-up and steady state
  • TOTAL row mixes different kinds of requests
  • No standard deviation or time-based charts
  • Screen updates cost processor time in the graphical interface
  • Can understate delay because virtual users wait for responses
i
Balance

The table is an excellent first look and a good companion to the dashboard, but never the only evidence. Combine it with time-based charts and server metrics before concluding.

29Best Practices Checklist

A short order of operations avoids the stumbles described in this guide.

1

Agree targets first

Decide which requests matter, which percentile judges them and what limits mean success.

2

Label carefully

Use stable business names and know how transaction controllers affect the rows.

3

Check the checks

Add assertions so the error column reflects real correctness, not just response codes.

4

Run headless for real load

Use the command line with a light writer; reserve the live table for small runs.

5

Focus on the steady state

Record phase boundaries and judge from the period when all users are active.

6

Read several columns together

Median, percentiles, errors, throughput and data rates tell the story only in combination.

7

Repeat, record and archive

Repeat runs to learn the noise, then save the raw file, the table export and a short note of every setting.

!
Common Mistake

Declaring victory on the first run. A single run cannot show how noisy your environment is, and an apparently good result may simply be a lucky one.

30Real-World Scenarios

Stories show how the table helps, and how it can mislead, in everyday projects.

The perfect average that hid a disaster

A team reported an average of under one second and declared success. A colleague opened the ninety-ninth percentile and found one request in a hundred taking nearly half a minute, caused by a database lock. Fixing it required no change to the average at all.

The overloaded server that looked fast

During a stress test the average response time fell sharply as users were added. The error column showed a rapidly growing share of rejected requests. The server was refusing work quickly, which flattered the timing columns.

The total row that passed everything

A report passed a release because the total row met its target. The checkout row, buried among thousands of cheap status calls, was missing its target by a wide margin. Judging each critical row separately revealed it.

The ramp-up that ate the test

A short test spent most of its time ramping up, so its table described a lightly loaded system. A longer steady state exposed slow responses that the original table had diluted away.

The controller that could not keep up

A distributed run with rich listeners on the controller showed strange timings. Moving to per-worker results files and analysing afterwards gave stable, believable numbers.

The unreadable table

An analyst included each account name in the sampler labels. The table grew thousands of rows with a single sample each. Switching to stable business labels made the results readable and safe to share.

31Frequently Asked Questions

Q1What is the difference between the Aggregate Report and the Summary Report?

The Aggregate Report shows median and percentile columns. The Summary Report shows standard deviation and average response size but no percentiles, and it is lighter on memory.

Q2What does the 90% Line column mean?

It is the time that ninety percent of samples did not exceed. One in ten requests took longer than that value.

Q3Can I change the percentile columns?

Yes. The three percentile values are set in JMeter’s property file, and a restart applies the change. Remember that older reports may have used different percentiles.

Q4Why is my average so much higher than my median?

A slow tail is pulling the average up. Look at the high percentiles and the maximum to see how bad the slow samples are.

Q5What exactly is throughput in this report?

The number of completed requests divided by the elapsed time, shown per second, minute or hour. It is a result of your test design, not a setting.

Q6Why does the table use so much memory?

To compute the median and percentiles it keeps individual elapsed times. Memory therefore grows with the number of samples, especially in long tests.

Q7Should I keep the Aggregate Report in a command-line run?

For large runs, no. Use a lightweight file writer and load the saved file into the table or the dashboard afterwards.

Q8How do I view a command-line run in the graphical table?

Open a plan containing an Aggregate Report, enter the path of the saved results file in its filename box and let it load. Allow enough memory for large files.

Q9Why are there extra rows for my transaction?

Depending on the transaction controller’s setting, it may add its own sample alongside the child samples, so both appear in the table and in the totals.

Q10Is the TOTAL row a good summary?

Only as background. It mixes different kinds of requests, so judge each critical request on its own row against its own target.

Q11Why does the error percentage show zero when users see errors?

Without assertions, error pages with normal response codes count as successes. Add content checks so failures are detected.

Q12How many samples do I need for a reliable ninety-ninth percentile?

There is no fixed number, but a few thousand per row gives much steadier values than a few hundred. Repeat runs to see how much the figure moves.

Q13Can I export the table to a spreadsheet?

Yes. Use the save-table button, include the header option, and open the file in a spreadsheet for comparison and charts.

Q14Should I use this report or the HTML dashboard?

Use the table for fast checks and the dashboard for shareable reports with charts over time. Many teams use both on the same results file.

32Summary and Key Takeaways

The Aggregate Report compresses a mountain of samples into one row per request, with counts, averages, medians, percentile lines, error shares, throughput and data rates. It is quick, readable and widely used, which is why it is so often misread. The average hides the slow tail, the TOTAL row blends unlike requests, error percentages depend on the assertions behind them, throughput reflects your test design, and the whole table blends ramp-up with steady state. Used with care, it is an excellent first look at a run. Read several columns together, judge each critical request against its own target, run heavy tests headless and analyse afterwards, and confirm the story with time-based charts and server metrics.

Key Takeaways

  • One row per label — stable business names make the table readable, and transaction settings change what appears and what is counted.
  • Never trust the average alone — read the median and percentile lines to see the slow tail that users actually remember.
  • Distrust the TOTAL row — it mixes unlike requests; judge each critical request on its own row against its own target.
  • Read errors honestly — add assertions so the error column reflects real correctness, and read timings together with the error share.
  • Throughput is a result — it follows from users, response time and think time, so design the test to aim for a required rate.
  • Focus on steady state — ramp-up and warm-up samples flatter or distort the figures; record phase boundaries and judge from the steady period.
  • Measure headless, analyse afterwards — use a light file writer for real load, load the saved file into the table or dashboard, and archive the raw results.