In a JMeter test plan, in what order do the elements around a single sampler run?
answer
- One sampler's turn has a fixed order
- Something configures, something pauses, something sends
- Three of the seven need a result
- The manual numbers the list from zero
basics
~10 sConfiguration elements first, then Pre-Processors, then Timers, then the Sampler, then Post-Processors, Assertions and Listeners. The last three are skipped when the sampler returns a null SampleResult.
solid answer
~40 sJMeter replays a fixed seven-step order for every sampler in a thread's turn: **config elements** are merged into the sampler, then **Pre-Processors** run, then **Timers** sleep, then the **Sampler** is invoked, then **Post-Processors**, **Assertions** and **Listeners** are given the result. The manual publishes exactly that list, and `JMeterThread.executeSamplePackage(...)` implements it call for call. The last three steps sit inside one `if (result != null)` guard, so a sampler that returns no `SampleResult` at all — the Flow Control Action sampler, for instance — skips extraction, checking and recording together. The order is by element *type*, not by vertical position: a Post-Processor drawn above a sampler still runs after it. Tree position only breaks ties within one type.
code
text · 9 linesThread Group
HTTP Cookie Manager <- 0 config element
Simple Controller
JSR223 PreProcessor <- 1 pre-processor
Constant Timer <- 2 timer
HTTP Request GET /cart <- 3 sampler
JSON Extractor <- 4 post-processor
Response Assertion <- 5 assertion
View Results Tree <- 6 listenergo deeper
Recall the seven steps in order and be able to say them without hesitating: config, pre-processor, timer, sampler, post-processor, assertion, listener.
Explain that the last three are guarded by a single null-result check, and that ordering is by element type with tree position only breaking ties inside one type.
Use the order to predict what a request carried and what a run recorded from the plan alone, and to say which of a plan's surprises are ordering and which are scope.
Own the convention that keeps this predictable across a team's plans: where correlation and verification elements live, and why an ordering mistake should be visible in review rather than only at run time.
## The order the manual publishes The JMeter user manual states the per-sampler order in *Test Plan → Execution order*, as a list numbered from zero: 0. **Configuration elements** 1. **Pre-Processors** 2. **Timers** 3. **Sampler** 4. **Post-Processors** (unless the `SampleResult` is `null`) 5. **Assertions** (unless the `SampleResult` is `null`) 6. **Listeners** (unless the `SampleResult` is `null`) That is one sampler's *turn*. The whole list is replayed from the top for the next sampler, and again for the next thread iteration. ## What the engine does `JMeterThread.executeSamplePackage(...)` is the method that runs the turn, and it reads exactly like the list: ```java SamplePackage pack = compiler.configureSampler(current); // 0: merge config elements runPreProcessors(pack.getPreProcessors()); // 1 delay(pack.getTimers()); // 2: sleep, then sample SampleResult result = null; if (running) { result = doSampling(threadContext, pack.getSampler()); } // 3 if (result != null) { threadContext.setPreviousResult(result); runPostProcessors(pack.getPostProcessors()); // 4 checkAssertions(pack.getAssertions(), result, ctx); // 5 notifyListeners(sampleListeners, result); // 6 } ``` Two details fall straight out of that code. First, `setPreviousResult(result)` runs immediately before the Post-Processors, which is why a JSR223 PostProcessor's `prev` binding holds *this* sampler's result. Second, everything after the sampler sits inside one `if (result != null)` block — the null qualifier is one shared guard, not three separate ones. ## The skip clause, and why it is one clause and not three A sampler is allowed to return no result at all. The stock example is the **Flow Control Action** sampler, whose `sample()` ends with `return null; // This means no sample is saved`. When that happens the engine falls to the `else` branch, calls `compiler.done(pack)` and moves on. So all three of Post-Processors, Assertions and Listeners are skipped together, and no row is produced for that element anywhere. Steps 0–2 are *not* conditional on a result, because they happen before the sampler is even invoked. A Timer under a Flow Control Action still sleeps; a Pre-Processor under it still runs. | Step | Runs when the sampler returns null? | Reason | |---|---|---| | Config elements | Yes | merged into the sampler before it is called | | Pre-Processors | Yes | executed before sampling | | Timers | Yes | the sleep happens before sampling | | Sampler | Yes | it is the thing that returned null | | Post-Processors | No | guarded by `if (result != null)` | | Assertions | No | same guard | | Listeners | No | same guard | ## Type order versus tree order The order above is by **element type**, not by vertical position in the plan. The manual is explicit: *"Logic Controllers and Samplers are processed in the order in which they appear in the tree. Other test elements are processed according to the scope in which they are found, and the type of test element. Within a type, elements are processed in the order in which they appear in the tree."* The manual's own worked example makes this concrete. A controller holding, in tree order, Post-Processor 1, Sampler 1, Sampler 2, Timer 1, Assertion 1, Pre-Processor 1, Timer 2, Post-Processor 2 executes as: - Pre-Processor 1, Timer 1, Timer 2, **Sampler 1**, Post-Processor 1, Post-Processor 2, Assertion 1 - then the same seven again around **Sampler 2** Note that Post-Processor 1 is drawn *above* both samplers and still runs after each of them, and that Timer 2 — drawn below Assertion 1 — still runs before the sampler. Position in the tree decides ordering only among elements of the same type. ## Two more preconditions worth naming - **No sampler, no processing.** The manual adds that Timers, Assertions, Pre- and Post-Processors *"are only processed if there is a sampler to which they apply"*. A Timer parked in a controller that contains no sampler never sleeps. - **User Defined Variables are the exception to step 0.** Every User Defined Variables element in the plan is processed at the start, wherever it sits, rather than at the top of each sampler's turn. ## What interviewers are testing They are checking whether you can predict what a request carries and what a run records, from the plan alone. The two facts that do most of that work are that timers are served *before* the request rather than after it, and that everything which reads a response — extraction, checking, recording — happens after the request has already gone out and come back.
- The manual's example puts a Post-Processor above two samplers in the tree. When does it run?After each sampler, once per sampler. Tree position orders elements only within a single type, so drawing a Post-Processor first does not make it run first. It is still a Post-Processor and still runs at step 4 for every sampler in its scope.
- What happens to a Timer that sits in a controller containing no sampler?Nothing. The manual states that Timers, Assertions, Pre- and Post-Processors are only processed if there is a sampler to which they apply. With no sampler in scope there is no turn to attach to, so the timer never sleeps and the thread is not delayed.
saying these in an interview costs you the question
- Says timers run after the sampler, as think time
- Says assertions run before post-processors
- Reads the order straight down the tree, ignoring element type
- Thinks a listener still logs a row when no SampleResult was produced
- Says config elements are applied only when a variable is referenced