skip to content

What do the five Grouping options of JMeter's HTTP(S) Test Script Recorder do?

level: middleimportance: should knowfreq 48%

answer

  1. Grouping guesses at user clicks
  2. The guess is made from timing gaps
  3. One property sets the default threshold
  4. Two options create a wrapping controller

basics

~20 s

Grouping decides how requests that arrived close together are laid out: not grouped, separated by a divider controller, wrapped in a Simple Controller, wrapped in a Transaction Controller, or reduced to the first sampler of each group.

solid answer

~50 s

The dropdown offers **Do not group samplers**, **Add separators between groups**, **Put each group in a new controller**, **Store 1st sampler of each group only** and **Put each group in a new transaction controller**. A new group starts when the gap since the previous recorded request exceeds the recorder's pause threshold — the `proxy.pause` property, default `5000` ms, overridden per recorder by the **Create new transaction after request (ms)** field — or when the Transaction name field changes. *Add separators* inserts a Simple Controller named with a row of dashes; *new controller* and *new transaction controller* create a Simple Controller or a Transaction Controller per group and drop the samplers into it. *Store 1st sampler only* keeps one sampler per group and switches Follow Redirects and Retrieve All Embedded Resources on so it fetches the rest itself.

go deeper

for a junior

Be able to name the option that wraps each group in a Transaction Controller and say that grouping is guessed from the pauses between requests. That is enough to read someone else's recorded plan.

for a middle

Explain all five options, the pause threshold and its property, and the fact that a changed Transaction name also opens a group. Say what Store 1st sampler only does to the surviving sampler.

for a senior

Show the recording discipline that makes grouping work: deliberate pauses or a renamed transaction between steps, and a review of the tree afterwards, because a fast operator produces one enormous group.

for a principal

Decide the team's convention. Grouping fixes the tree shape and therefore how results are reported per step, so leaving it to each engineer guarantees plans that cannot be compared release to release.

A browser click is not one request. It is a document plus twenty assets plus a couple of background calls, arriving within a few hundred milliseconds of each other. Grouping is the recorder's answer to that: it uses the *gaps between requests* to guess where one user action ended and the next began, and then lays the tree out accordingly. ## What makes a group The recorder timestamps each recorded sample and compares the gap to a threshold. A new group begins when either: - the gap since the previous recorded sample is **larger than the threshold**, or - the recorder's **Transaction name** field has changed since the previous sample — which is how the floating recorder dialog lets you name steps as you browse. The threshold comes from the `proxy.pause` property, whose default is `5000` milliseconds. The recorder's own **Create new transaction after request (ms)** field overrides it for that element when it is non-empty. The practical consequence is a discipline: while recording, pause deliberately between the actions you want to become separate steps, or rename the transaction before each one. Click straight through and everything lands in one group. ## The five options | Option | What it puts in the tree | | --- | --- | | `Do not group samplers` | Samplers appended one after another, no structure at all | | `Add separators between groups` | A Simple Controller named with a row of dashes between groups; samplers still sit flat | | `Put each group in a new controller` | A Simple Controller per group, samplers nested inside it | | `Store 1st sampler of each group only` | Only the first sampler of each group survives | | `Put each group in a new transaction controller` | A Transaction Controller per group, samplers nested inside it | The last option is the one the bundled **Recording** template selects, and it is usually what you want: each user action becomes one named Transaction Controller, so the results afterwards are per step rather than per asset. The Transaction Controllers the recorder creates are made with the "include duration of timers and pre/post processors" option switched off, and each one is named from the recorder's Transaction name field. ## The special case worth knowing `Store 1st sampler of each group only` does more than throw the other samplers away. The surviving sampler has **Follow Redirects** and **Retrieve All Embedded Resources** switched on, so at replay it re-fetches the assets it was recorded alongside instead of replaying them as literal samplers. That trades a small tidy plan for two things the plain recording did not have: the embedded-resource parsing cost moves to the injector, and the exact set of assets is no longer pinned. Those flags belong to the HTTP Request sampler, and `dev-jmeter-protocols-http-sampler` owns what they do once the plan runs. ## Things that attach only to the first sampler Grouping does not just shape the tree; it decides what else the recorder attaches. Two elements land on the sampler that *opens* a group rather than on every sampler: 1. **Add Assertions** — the blank assertion the checkbox requests; 2. any **timer placed inside the recorder element**, which is copied onto the group's first sampler with `${T}` replaced by the measured gap since the previous recorded sample. The bundled *Recording with Think Time* template uses exactly that, with a Uniform Random Timer whose delay is `${T}`. The timers themselves — what a Uniform Random Timer does at run time, where a pause takes effect — are `dev-jmeter-load-delay-timers` material; the copying is the recorder's. ## Choosing one - Recording a single short journey you will restructure by hand anyway: **Do not group samplers** keeps it honest. - Recording several journeys in one sitting and you want to see the seams: **Add separators between groups**. - Recording something you intend to report on per step: **Put each group in a new transaction controller**, and name each step in the recorder dialog before you click. - Recording a page-level plan where assets should be fetched rather than scripted: **Store 1st sampler of each group only**. Whatever you pick, the grouping is guesswork built on timing. Review the tree afterwards: a fast operator produces one enormous group, and a distracted one produces a group per request.

  • You recorded a five-step journey and every request ended up in one group. Why?
    The gaps between your clicks never exceeded the threshold — `proxy.pause`, default 5000 ms, or whatever the Create new transaction after request (ms) field holds. Either pause for longer than that between actions, lower the threshold, or change the Transaction name in the recorder dialog before each step, which also forces a new group.
  • Does a timer inside the recorder element get copied onto every recorded sampler?
    It is copied onto the sampler that opens each group, not onto every one. Any `${T}` in the copied timer's fields is replaced with the measured gap in milliseconds since the previous recorded sample, which is how the Recording with Think Time template turns real browsing pauses into plan delays.

saying these in an interview costs you the question

  • Thinks grouping inspects the HTML to work out page boundaries
  • Says the threshold is fixed and cannot be changed
  • Believes Store 1st sampler only simply deletes the other requests
  • Confuses the separator controller with a Transaction Controller
  • Expects assertions to be added to every recorded sampler