Understanding the execution order of JMeter components is the key to avoiding bizarre, hard-to-debug issues. Many beginners place elements in the wrong order or wrong scope and then wonder why their extractors do not work or their timers apply to the wrong requests. Let me lay this out clearly once and for all.
For each sampler, JMeter executes components in this fixed order. It does not matter where they appear visually in the tree -- the order is always the same.
Scope determines which samplers an element applies to. The rules are simple but critical. An element applies to all samplers that are siblings (same level) or descendants (children, grandchildren) of its parent. An element under a specific sampler applies ONLY to that sampler.
Thread Group
├── HTTP Header Manager ← Scope: ALL requests in this Thread Group
├── Constant Timer (2000ms) ← Scope: ALL requests in this Thread Group
├── HTTP Request: Login
│ ├── JSON Extractor: token ← Scope: ONLY Login request
│ └── Response Assertion: 200 ← Scope: ONLY Login request
├── HTTP Request: Get Products
│ └── Duration Assertion: 1000 ← Scope: ONLY Get Products
├── HTTP Request: Add to Cart
├── View Results Tree ← Scope: ALL requests in this Thread Group
└── Summary Report ← Scope: ALL requests in this Thread Group
# The Header Manager adds headers to Login, Get Products, AND Add to Cart.
# The Constant Timer delays Login, Get Products, AND Add to Cart.
# The JSON Extractor runs ONLY after Login.
# The Duration Assertion checks ONLY Get Products.
# Both listeners capture ALL three requests.| Mistake | What Happens | Fix |
|---|---|---|
| Timer under Thread Group + Timer under Sampler | Both timers apply to that sampler (additive) | Use one or the other, not both |
| Extractor at Thread Group level | Runs after EVERY request, overwriting variables | Place extractors under the specific sampler |
| Assertion at Thread Group level | Runs on ALL requests (may not be appropriate) | Place under specific samplers unless you want global checks |
| Header Manager under one sampler | Applies ONLY to that sampler (parent headers are replaced) | Put common headers at Thread Group level |
| Config Element inside a Logic Controller | Only applies to samplers inside that controller | Move to Thread Group level for global scope |
The most common bug: placing a JSON Extractor at the Thread Group level instead of under the specific sampler. The extractor runs after EVERY request and overwrites your variable with whatever the last response contained. Always place extractors directly under the sampler whose response you want to extract from.
When in doubt about scope, use this mental model: "Draw a box around the parent element. Everything inside the box is in scope." If a Header Manager is inside the Thread Group box, it applies to all requests inside that box. If it is inside a Transaction Controller box, it only applies to requests inside that controller.
Key Point: Execution order is fixed: Config → Pre-Processor → Timer → Sampler → Post-Processor → Assertion → Listener. Scope = everything under the same parent. Place extractors under specific samplers, not at Thread Group level.
Key Point: Execution order: Config → Pre-Processor → Timer → Sampler → Post-Processor → Assertion → Listener. Scope = same parent. Place extractors under the right sampler.