JMeter Logic Controllers: If, Loop, and Transaction Controllers

How JMeter's Logic Controllers (If Controller, Loop Controller, Transaction Controller) shape test flow and how to use them without breaking your results.

· By perf-test.com Editorial · AI-assisted
jmeterlogic-controllersscripting

Logic Controllers determine the order and conditions under which samplers execute. They don’t generate requests themselves — they control flow around the samplers that do.

Transaction Controller — the most important one for reporting

Groups multiple samplers into a single logical “transaction” in the results (e.g. group a login page’s HTML request, CSS, and JS into one “Login Page” transaction rather than three separate rows). Check “Generate parent sample” to roll up timing into one aggregate result; this is essential for making reports readable when a single business transaction spans several HTTP requests, and it’s the standard way to measure “checkout flow” or “search and view results” as one meaningful unit rather than a pile of individual request rows.

If Controller

Executes its children only if a condition (a JMeter expression evaluating to true/false) holds — for example, only attempt a “retry” sampler if a previous extractor failed to find a value, or branch behavior based on a parameterized user “type” (free vs. paid tier) to model realistic traffic mix.

Loop Controller

Repeats its children a fixed number of times, independent of the Thread Group’s own loop count — useful for modeling a sub-flow that repeats more or less often than the outer test iteration (e.g. “add 3 items to cart” inside one larger checkout iteration).

Once Only Controller

Executes its children exactly once per thread, regardless of the Thread Group’s loop count — the standard place for login, which should happen once per virtual user session, not once per loop iteration if the Thread Group loops multiple times to simulate a longer session.

Random Controller / Throughput Controller

Random Controller picks one of its children at random each time it executes — useful for modeling varied user behavior (some users search, some browse categories) without scripting separate Thread Groups for each. Throughput Controller executes its children a target percentage of the time, giving more deterministic control over traffic mix than pure randomness (e.g. exactly 70% of iterations browse, 30% search).

Interleave Controller

Alternates between its children on successive executions rather than running them all every time — useful for round-robining between multiple API endpoints or test data variants.

A realistic composition

A common, realistic structure: Once Only Controller (login) → Loop Controller or the Thread Group’s own loop (main session) → Throughput Controller (mix of browse/search/purchase behavior) → Transaction Controllers wrapping each business flow for clean reporting. Building scripts this way, rather than as one flat list of samplers, is what makes a JMeter test plan actually represent realistic user behavior instead of a mechanical repeat of one fixed sequence.

Takeaway: Transaction Controllers are worth adding to almost every non-trivial script purely for reporting clarity — without them, a report full of individual request rows makes it hard to reason about business-level performance at all.

Discussions coming soon.

Comments are powered by Giscus (GitHub Discussions). Enable them by configuring GISCUS in src/consts.ts — see giscus.app.