The Once Only Controller in JMeter: Do It One Time, Then Move On

The Once Only Controller in JMeter: Do It One Time, Then Move On

A deep, plain-English guide to the controller that runs its steps only on a virtual user's first pass, covering how it works inside, how it behaves in loops, how it differs from its alternatives, and the traps that quietly distort load test results.

Think about visiting a large office building. At the front desk you show your identity card and receive a visitor badge. After that you spend the whole day walking between meeting rooms, and nobody asks you to return to the desk and prove who you are before every single door. The badge check happens once, at the start of your visit, and everything after it relies on the badge you already hold.

A realistic performance test should behave in the same sensible way. A virtual shopper signs in once and then browses, searches and buys many times. If your test makes every virtual user sign in again at every loop, you are measuring a world that does not exist. JMeter offers a small, humble element for exactly this situation, called the Once Only Controller. This guide explains it from zero knowledge, shows how it works inside, and teaches you where it helps, where it misleads and what to use instead.

1What the Once Only Controller Is and Why It Exists

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

The repetition problem

A JMeter virtual user, called a thread, normally walks through its steps from top to bottom and then, if the test says so, walks through them again. Each walk is called an iteration. This repetition is what generates sustained load. The trouble is that some steps in a real journey are not repeated by real people. Signing in, accepting terms and conditions, downloading a configuration file or opening a long-lived connection usually happen once per visit, not once per action.

The solution in one sentence

The Once Only Controller is a container. Whatever steps you place inside it are executed during each thread’s first iteration only, and are skipped on every later iteration. The thread then continues with the rest of its journey as normal.

What happens without it

Without a way to run steps once, test authors tend to fall into one of two poor habits. Some put the sign-in at the top of the repeated section, so every iteration signs in again and the authentication system receives many times its real traffic. Others try to avoid sign-in altogether by pasting a fixed token into every request, which means the test never exercises real sessions and every virtual user pretends to be the same person. Both habits produce numbers that look precise and mean very little. The Once Only Controller gives a third, far more honest option.

Why it matters for accuracy

If sign-in were repeated in every iteration, the authentication system would receive far more traffic than in real life, and the rest of the journey would receive less, because time is wasted signing in again. The numbers would blame the login service for slowness that real users never see, while hiding how the actual pages behave. A single small controller removes this distortion.

Simple Analogy

Think of a theatre. You buy a ticket once at the box office and then watch many scenes. The Once Only Controller is the box office: every audience member passes through it once, at the start, and the play that follows never asks for the ticket again.

Once
per virtual user, not per test
First
pass through the surrounding loop
Skipped
on every pass after that

2Core Concepts You Need First

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

Term 1

Thread

One virtual user. Ten threads means ten simulated people acting at the same time, each with their own private state.

Term 2

Iteration

One complete walk through the steps a thread has been told to repeat. A thread set to loop twenty times performs twenty iterations.

Term 3

Logic Controller

An element that decides which of its children run, in what order and how often. It does not send requests itself.

Term 4

Sampler

The element that actually sends a request and records the outcome, such as a web call or a database query.

Term 5

Thread Group

The element that defines how many virtual users run, how fast they start and how many times they repeat.

Term 6

Variable

A named value that belongs to one thread, such as a token that user received. Other threads cannot see it.

Term 7

Property

A named setting shared by every thread in the test. This difference between private variables and shared properties becomes important later.

Term 8

Session

The conversation between a user and an application after sign-in, usually tracked by a cookie or a token.

i
Remember

The Once Only Controller counts per thread. It never means “once for the whole test”. That single distinction prevents the most common mistakes covered later in this guide.

3Where It Fits Among Logic Controllers

The Once Only Controller is one member of a family, and seeing its relatives clarifies its purpose.

ControllerWhat It DecidesTypical Use
Simple ControllerNothing; it only groups childrenOrganising a plan
Loop ControllerRepeat children a set number of timesRepeating an action
Once Only ControllerRun children on the first pass onlyLogin and one-time setup
If ControllerRun children only if a condition is trueConditional steps
While ControllerRepeat children while a condition holdsPolling until ready
Interleave ControllerRun one child per pass, rotatingAlternating actions
Random ControllerRun one randomly chosen childVaried behaviour
Throughput ControllerRun children a percentage or number of timesTraffic mix control
Transaction ControllerGroup children into one timed unitBusiness-level timing
flowchart TD
  T[Thread Group] --> O[Once Only Controller]
  T --> L[Loop of repeated actions]
  O --> A[Login request]
  O --> B[Fetch settings request]
  L --> C[Browse products]
  L --> D[Search]
  L --> E[Add to basket]
        
FIG 1 — A typical plan: one-time setup beside the repeated journey
i
Reading the Picture

The Once Only Controller sits beside the repeated work, not around it. Its children run in the first iteration, and the thread then carries on with everything else in the group.

4How It Works Inside

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

Each thread carries its own tree

When a test starts, every thread receives its own private copy of the parts of the plan it will run, along with its own state. This is why one user’s variables are invisible to another. The Once Only Controller lives inside that private copy, so its memory of whether it has already run belongs to that one thread. Thread number seven having completed its sign-in says nothing about thread number eight.

The first-iteration rule

When the thread reaches the controller, it asks one question: is this the first iteration of my enclosing loop? If yes, the controller passes the thread into its children, which then run in the order they appear. If no, the controller steps aside and the thread moves directly to the next element. No request is sent, no time is recorded and nothing appears in the results for that skipped pass.

The controller itself produces no sample

A logic controller is not a sampler. The Once Only Controller adds no timing of its own. What you see in the results are only the samples of the children that actually ran. If you want one combined timing for the whole sign-in sequence, wrap the children in a Transaction Controller inside it.

sequenceDiagram
  participant U as Virtual User
  participant O as Once Only Controller
  participant S as Login Sampler
  participant J as Journey Samplers
  U->>O: Iteration 1 arrives
  O->>S: Run children
  S-->>U: Login result and token
  U->>J: Browse and search
  U->>O: Iteration 2 arrives
  O-->>U: Skip children
  U->>J: Browse and search again
  U->>O: Iteration 3 arrives
  O-->>U: Skip children
  U->>J: Browse and search again
        
FIG 2 — One virtual user across three iterations
Simple Analogy

Imagine a security guard with a clipboard, one clipboard per visitor. The first time a visitor arrives, the guard performs the ID check and ticks the box. On every later arrival the guard sees the tick and waves the visitor through. Each visitor has a separate clipboard, so one visitor’s tick never excuses another.

!
Common Misconception

Believing the controller keeps a single global flag for the entire test. It does not. If a hundred threads run the plan, the children run a hundred times in total, once for each thread.

5The Loop Rule: Behaviour Under a Parent Loop

The controller is often misunderstood when it sits inside another looping controller, so this chapter takes it slowly.

The rule as documented

The official description says that the Once Only Controller runs during the first iteration of whatever looping parent surrounds it. When it sits directly under a thread group, that means the first iteration of the thread’s own loop, which is the familiar once-per-user behaviour. When it sits inside a Loop Controller, the first iteration of that loop is meant, and this happens again every time the outer thread loop brings the thread back into that Loop Controller.

A worked example in words

Suppose a thread group makes each user repeat three times. Inside it sits a Loop Controller set to loop five times, and inside that Loop Controller sits a Once Only Controller followed by a search sampler. On the thread’s first outer pass, the Loop Controller begins, and on its first inner iteration the Once Only children run once. Inner iterations two to five skip them. On the thread’s second outer pass, the Loop Controller starts afresh, so its first inner iteration again runs the Once Only children. By the end, the children have run three times, once per outer pass, not once in total.

1

Outer pass 1, inner loop 1

The once-only children run, then the search runs.

2

Outer pass 1, inner loops 2 to 5

The once-only children are skipped; only the search runs each time.

3

Outer pass 2, inner loop 1

The inner Loop Controller starts fresh, so the once-only children run again.

4

Outer pass 2, inner loops 2 to 5

Skipped again, with only the search running.

!
Common Mistake

Placing the controller inside a Loop Controller and expecting a single execution per user. If you truly need once per user, place it directly in the thread group, outside any inner loop.

“Once only means once per trip through the loop that contains it.”

6A Walkthrough: Sign In Once, Then Browse

The classic use case, built step by step, makes the idea concrete.

The scenario

An online store wants to know how its catalogue pages behave when two hundred shoppers browse at the same time. Each shopper signs in, then repeatedly opens a category page, a product page and a search result. The goal is to measure the browsing pages, not the sign-in.

1

Create the thread group

Set two hundred users, a sensible ramp-up and either a fixed loop count or a duration. Leave the option that keeps the same user across iterations switched on.

2

Add the Once Only Controller first

Place it directly under the thread group, above the repeated browsing steps.

3

Put the sign-in inside it

Add the sign-in request, and an extractor if the response contains a token that later requests need.

4

Add the browsing steps after it

Category page, product page and search follow, outside the controller, so they repeat every iteration.

5

Add shared helpers

A cookie manager or a header manager at thread-group level supplies the session to every request.

6

Prove it with one user

Run a single user for several iterations with a results viewer and confirm the sign-in appears only in the first iteration.

When sign-in has several steps

Real sign-in is rarely one request. A user may load the sign-in page, receive a security token embedded in it, submit credentials, and then be redirected to a landing page that sets further cookies. All of these steps belong together inside the controller, in their true order, so that the session is complete before the browsing begins. If only the final credential submission is inside the controller and the earlier page load is outside it, the page load will repeat on every iteration, wasting traffic and confusing your counts.

flowchart LR
  A[Thread starts] --> B{First iteration?}
  B -- Yes --> C[Run sign-in once]
  B -- No --> D[Skip sign-in]
  C --> E[Browse category]
  D --> E
  E --> F[Open product]
  F --> G[Search]
  G --> H{More iterations?}
  H -- Yes --> B
  H -- No --> I[Thread ends]
        
FIG 3 — The decision the controller makes at the start of every iteration
i
Practical Note

The sign-in request will appear exactly as many times in your results as there are threads. That number is a useful self-check: if you see far more sign-ins than users, something is wrong with placement.

7Per-Thread Versus Per-Test: The Biggest Confusion

Many people reach for this controller when what they really need is something that runs once for the entire test.

Two very different needs

Some work must happen once per virtual user, such as that user’s own sign-in. Other work must happen once for the whole test, such as creating a shared set of products, preparing a database, or fetching one administrator token that every thread reuses. The Once Only Controller serves the first need only. If you place a data creation step in it, and you run five hundred threads, the step runs five hundred times, which may be exactly the problem you were trying to avoid.

NeedRight ToolWhy
Each user signs in onceOnce Only ControllerRuns once per thread
Prepare shared data before the testsetUp Thread GroupRuns before the main thread groups, a single time
Clean up after the whole testtearDown Thread GroupRuns after the main thread groups finish
Run something a fixed number of times across all usersThroughput Controller in total-executions modeCounts executions across the test
Run a step only for the first userIf Controller with a thread-number conditionUses the thread’s own number as the test
Simple Analogy

A hotel has two kinds of one-time jobs. Each guest checks in once, which is like the Once Only Controller. But the hotel is built once for all guests, which is like a setup thread group. Mixing them up would mean rebuilding the hotel for every arriving guest.

!
Common Mistake

Putting an administrator action such as “create test catalogue” inside the Once Only Controller. With many users, you will create many catalogues, pollute the system under test, and invalidate the run.

8Variables, Cookies and Session State

Running sign-in once only helps if the result of that sign-in survives to later iterations, and that is not automatic.

Variables persist per thread

A value extracted during the first iteration, such as a token or a user identifier, is stored in a variable that belongs to that thread. In normal circumstances it remains available in every later iteration, because variables are not cleared between iterations. This is what allows the browsing steps to use a token obtained once at the start.

It helps to remember the difference between a variable and a property here. A variable belongs to one thread and is the correct home for personal values such as a token. A property is shared by the whole test, so storing a personal token there would make every user overwrite everyone else’s. If you ever need to hand a value from a setup group to the main users, a property is the right bridge, but a token that identifies one user must stay in that user’s own variable.

Cookies and the same-user setting

Web sessions often live in cookies. Two settings can silently erase them. The thread group has an option, usually described as using the same user on each iteration, which is normally switched on. When it is switched off, JMeter treats each iteration as a brand new browser: cookies, caches and connections are reset. The cookie manager also has its own option to clear cookies at the start of every iteration. If either is active, the session created in the first iteration vanishes, and from the second iteration the user is effectively signed out, but the sign-in never runs again.

Check 1

Same User Each Iteration

Keep it enabled when using the Once Only Controller for login, so the session survives.

Check 2

Cookie Manager Clearing

Make sure the option to clear cookies each iteration is switched off for sign-in-once designs.

Check 3

Cache Manager Clearing

Decide deliberately whether the browser cache should persist; it affects how many requests reach the server.

Check 4

Token Variables

Confirm tokens are stored in thread variables and that no later step overwrites them accidentally.

!
Symptom to Recognise

Everything works in iteration one and then every later request returns an authorisation error or a redirect to the sign-in page. This pattern almost always means session state was cleared between iterations.

9The Alternatives and When Each Wins

The Once Only Controller is one tool among several, and each alternative solves a slightly different problem.

setUp Thread Group

A special thread group that runs before every regular thread group and finishes before they start. It is the right place for one-time preparation of the environment, such as creating shared accounts or fetching a single shared credential. Values it produces can be shared with other thread groups through properties, because ordinary variables are private to a thread.

tearDown Thread Group

The mirror image, running after the regular groups end. It is the correct place for cleanup, such as deleting test data, because the Once Only Controller can only act on the first iteration, never the last.

Throughput Controller in total-executions mode

Runs its children a chosen number of times across all threads together. With a count of one and the per-user option off, the children run exactly once in the whole test, no matter how many threads exist. A per-user option changes the counting to each thread separately.

If Controller with a condition

Runs its children only when a condition is true. By testing something such as whether a token variable is already filled, it can sign a user in only when needed, which also lets a user sign in again after the token expires.

Separate thread group for sign-in tests

If the goal is to measure the sign-in service itself, a dedicated thread group where sign-in is the repeated action gives far better statistics than a once-only step that runs only at the start.

Include or Module Controller

These reuse a block of steps in several places. Combined with the Once Only Controller they keep a plan tidy when the same one-time sequence is needed in more than one scenario.

i
Rule of Thumb

Ask who the “once” belongs to. If it belongs to each user, use the Once Only Controller. If it belongs to the whole test, use setUp or a total-executions Throughput Controller.

10Choosing the Right Approach

A decision table turns the options into a confident choice.

Your SituationChooseReason
Every user must sign in once and keep a sessionOnce Only ControllerSimple, readable and per-user
All users share one administrator tokensetUp Thread GroupOne fetch, shared through a property
Session tokens expire during a long testIf Controller with a freshness checkAllows repeated sign-in when needed
You want to measure sign-in capacityDedicated login thread groupMany samples give reliable statistics
Something must run exactly once in the whole testThroughput Controller, total executionsCounts across threads
Cleanup after the testtearDown Thread GroupRuns once after all load ends
Each iteration should be a brand new visitorNo controller; disable same-user settingResets cookies and caches each pass

Three questions to ask

First, who owns the repeated action in real life, the user or the system? Second, how long will the test run compared with how long a session or token stays valid? Third, what is the purpose of the test: to measure the repeated journey, or to measure the one-time step? Answering these three questions usually reveals the right element within a minute.

“Choose the tool by asking whose ‘once’ it is.”

11What It Does to Your Reports and Statistics

Because the controller skips work, the numbers in your report look different, and that difference needs interpreting.

Sample counts reflect execution

Every sampler inside the controller produces one sample per execution. With two hundred threads, you will see about two hundred sign-in samples, while the browsing requests may number in the tens of thousands. This is correct and expected, but it affects how much you can trust each row of the statistics table.

Percentiles need enough samples

A ninety-fifth percentile computed from two hundred samples is far less stable than one computed from fifty thousand. A single slow sign-in changes the figure noticeably. When the sign-in row of your report looks alarming, check the number of samples before panicking, and rerun if necessary.

Throughput is not constant

Sign-in requests happen only when users arrive, so their rate depends on the ramp-up and then drops to zero. The rate of sign-ins over time therefore looks like a bump at the start of the test, not a steady line. This is the realistic shape for a one-time action, but it surprises people who expected a flat chart.

Few
samples for one-time steps
Many
samples for repeated steps
Bump
shape of one-time step rate over time
i
Reporting Tip

Label one-time steps clearly, for example with a prefix, so readers of the report immediately understand why their sample count is small and do not compare them unfairly with repeated steps.

!
Common Mistake

Quoting the sign-in average from a once-only test as if it were the sign-in service’s steady-state capacity. It only reflects the arrival burst of the ramp-up, a very different question.

12Ramp-Up and the Shape of Once-Only Load

The rate at which users start decides how hard the one-time steps hit the system.

Arrival rate equals users divided by ramp-up

If two hundred users start over one hundred seconds, about two new users begin every second, and each new user triggers one sign-in. The authentication service therefore sees roughly two sign-ins per second during the ramp, and nothing afterwards. If you shorten the ramp to ten seconds, the same two hundred sign-ins arrive at about twenty per second, a tenfold increase in pressure on that one service.

Why this matters

Real systems often face sign-in storms at particular moments, such as the start of a working day or a sale. A test that ramps users slowly will never reveal weakness in sign-in. A test that ramps users abruptly may overstate the problem if real arrivals are gentler. Choose the ramp-up to match the arrival pattern you want to study, and state it in your test notes.

Estimating the sign-in load before you run

You can predict the pressure on the authentication service with simple arithmetic. Divide the number of threads by the ramp-up time in seconds to get the arrival rate, then compare it with the rate the service handles in production at its busiest moment. If your plan produces ten times the real peak, you are running a stress test of sign-in, not a realistic test of browsing, and you should say so in your notes. If it produces a tenth of the real peak, you will learn nothing about sign-in capacity. Doing this sum takes a minute and prevents many arguments after the results arrive.

flowchart LR
  A[Short ramp-up] --> B[High sign-in rate at the start]
  B --> C[Stress on authentication service]
  D[Long ramp-up] --> E[Gentle sign-in rate]
  E --> F[Browsing load dominates]
  C --> G[Different bottlenecks found]
  F --> G
        
FIG 4 — The ramp-up shapes which part of the system is stressed
Simple Analogy

Imagine a concert venue with a ticket check at the door. If the crowd arrives over three hours, the door staff cope easily. If everyone arrives in ten minutes, a queue forms at the door even though the concert hall itself is perfectly fine. The ramp-up decides which situation your test creates.

i
Planning Tip

Run two versions of the test: one with a realistic ramp-up for browsing behaviour, and one with a deliberately aggressive ramp-up to stress the sign-in. Compare the results rather than trusting a single arrangement.

13Token and Session Expiry in Long Tests

A sign-in that happens only once can outlive the session it created, and the test then quietly turns into a test of error pages.

The hidden clock

Most applications give sessions and tokens a lifetime, often measured in minutes. A test that runs for an hour with a token valid for twenty minutes will see healthy results for the first twenty minutes and then a flood of authorisation failures. Because the sign-in was a once-only step, nothing in the plan ever refreshes the token.

Ways to handle it

1

Know the lifetime

Ask the application team how long a session or token stays valid and whether activity extends it.

2

Compare with the test length

If the test is shorter than the lifetime, once-only sign-in is perfectly safe.

3

Add a refresh path

For longer tests, store the time of sign-in in a variable and use a conditional controller to sign in again when the token is close to expiry.

4

Or use a refresh endpoint

If the application provides a refresh operation, call it periodically in the repeated part of the journey.

5

Assert on authorisation

Add assertions or error checks that clearly flag expired sessions so they cannot hide inside an average.

ANTI-PATTERN-01 Avoid
Problem

A two-hour soak test signs users in once and then repeats the journey for the entire duration.

Why It’s Harmful

After the token expires, most requests fail or are redirected. The report shows a rising error rate that is blamed on the application, when the real cause is the test design.

Correct Approach

Match the sign-in strategy to the session lifetime, either by refreshing tokens or by repeating sign-in at the real interval users would experience.

14Test Data and Data-File Interactions

Data files and one-time steps can interfere with each other in surprising ways.

The credentials file

Tests commonly read usernames and passwords from a file, giving each thread its own row. The data-file element reads a new row as threads iterate. If it advances every iteration while the sign-in runs only in the first, the user-name variable on later iterations will belong to a different person than the one who actually signed in. Later requests that quote the username, such as a profile page or an order history, may then ask for someone else’s data.

Ways to stay consistent

Approach 1

Copy at Sign-In

Right after sign-in, store the username in a differently named variable that is not touched by the data file again.

Approach 2

Control File Scope

Place the data-file element so it is read only where needed, and check its sharing mode against your intention.

Approach 3

Avoid Reusing Quoted Values

Prefer identifiers from the sign-in response to values read from the file when later requests need user context.

Approach 4

Size the File Properly

Provide at least one row per thread, and decide what happens when the file ends, so users do not share accounts unintentionally.

!
Common Mistake

Two threads signing in with the same account at the same time. Many applications limit simultaneous sessions per account, so the second sign-in may log out the first, producing errors that have nothing to do with performance.

i
Verification Tip

Add a small check that confirms the signed-in identity on a later iteration, for example by asserting that a profile page shows the expected name. It quickly catches mixed-up data.

15Timers, Assertions and Extractors Around the Controller

Supporting elements follow scope rules, and the Once Only Controller changes what falls inside that scope.

Scope decides who is affected

Timers, assertions and extractors apply to the samplers in their scope, which means the samplers at or below their position in the tree. A timer placed inside the Once Only Controller delays only the one-time steps. A timer placed at thread-group level delays every sampler, including those inside the controller. Decide on purpose where each helper belongs.

Think time for the first iteration

Real people pause after signing in, often to look at the landing page. A short think time after the one-time steps makes the first iteration resemble real behaviour. Without it, many users hit their first browsing request in the same instant they finish signing in.

Extractors must be reliable

If the extractor that captures the token fails during the one-time sign-in, nothing will retry it. Every later iteration will then use an empty or stale value. Always add an assertion directly on the sign-in request and consider stopping the thread if sign-in fails, since continuing would only create a stream of meaningless errors.

Failure handling for the sign-in

Set the thread group’s behaviour after a sampler error to stop that thread. A user who could not sign in has nothing useful to do, and letting it continue pollutes your results.

Assertions that prove the session

Check that the sign-in response contains the expected marker, not merely a success code. Some systems return a success code together with an error message in the body.

Timer placement

Use one timer inside the controller for post-sign-in pauses and a separate timer in the repeated section for normal think time, so each represents a different human behaviour.

“A one-time step that fails silently poisons every step that follows.”

16Placement and Nesting Rules

Where you put the controller matters as much as what you put inside it.

Directly under the thread group

The most common and most predictable placement. The children run in each user’s first iteration of the thread loop. Put it above the repeated steps so the one-time work happens first.

Inside a Loop Controller

The children run on the first inner iteration each time the loop starts, which may be many times per user, as described earlier. Useful when each cycle of an outer loop is a separate session, but rarely what a beginner wants.

Inside a Transaction Controller

A Transaction Controller around the Once Only Controller records a combined time for the one-time sequence, but only on iterations where something actually ran. On skipped iterations the transaction may show nothing meaningful, so check how your report treats it.

Inside an If Controller

Allowed, and sometimes useful, but conditions evaluated on later iterations may never be reached by the once-only logic, making the behaviour confusing to read. Prefer clearer designs.

Inside a Random or Interleave Controller

Legal but unpredictable. A rotating or random choice may not select the once-only branch on the first iteration at all, so the one-time step might never run. Avoid unless you understand the rotation exactly.

Inside reusable fragments

When a one-time block is placed in a reusable fragment and included from several places, each inclusion counts independently according to the parent loop where it sits. Test each inclusion separately.

i
Simplicity Rule

When in doubt, place the controller directly under the thread group and keep it away from clever combinations. The easiest plan to read is also the easiest to trust.

17Behaviour in Distributed Tests

When several machines generate load together, the word “once” still means once per thread, and the numbers multiply.

Each worker runs the whole plan

In a distributed test, the controller machine sends the full plan to every worker, and each worker runs its own set of threads. Thread counts therefore apply per worker. The Once Only Controller operates inside each thread, exactly as before, so the total number of one-time executions equals the total number of threads across all workers.

What this means for shared steps

If you place a “create shared data” step in a Once Only Controller and run three workers with a hundred threads each, that step runs three hundred times. For one-time work that belongs to the whole test, use the setUp thread group, remembering that in distributed mode it also runs on each worker, so shared preparation should be idempotent or done outside JMeter.

flowchart LR
  C[Controller] --> W1[Worker 1: 100 threads]
  C --> W2[Worker 2: 100 threads]
  C --> W3[Worker 3: 100 threads]
  W1 --> S1[100 sign-ins]
  W2 --> S2[100 sign-ins]
  W3 --> S3[100 sign-ins]
  S1 --> A[Authentication service sees 300 sign-ins]
  S2 --> A
  S3 --> A
        
FIG 5 — One-time steps multiply across workers
!
Common Mistake

Forgetting that the sign-in data file must exist on every worker with enough distinct accounts. If each worker reads the same first rows, three workers will sign in with the same accounts at once.

i
Practical Note

Split the credentials into separate files per worker, or provide a worker-specific property that selects a different range of accounts for each machine.

18Debugging the Controller

Because the controller hides work, bugs show up as things that did not happen, which are harder to notice.

1

Run one user for several iterations

Use at least three iterations so you can see the difference between the first and later passes.

2

Open a detailed results viewer

Confirm the sign-in appears once, at the very beginning, and never again.

3

Inspect variables after each iteration

A debug element placed in the repeated section shows whether the token and user variables are still filled.

4

Check request headers on later iterations

Verify that the token or cookie is actually being sent in iteration three, not just in iteration one.

5

Try two users

Confirm each user has their own token and that their data does not mix.

6

Count the sign-ins in a larger run

The total should equal the thread count. Any other number means the controller is placed or configured differently from what you intended.

i
Symptom Guide

If sign-ins are too many, the controller is probably inside a loop. If later requests fail with authorisation errors, session state was probably cleared or the token expired. If sign-ins are missing for some users, the controller may sit under a branching element that did not select it.

19GUI Mode Versus Command-Line Mode

The controller behaves identically in both modes, but your way of working should differ.

Same logic, different purpose

The skipping logic lives inside the engine, so the plan behaves the same whether it is run from the graphical interface or from the command line. Use the graphical interface to build the structure and to prove with one or a few users that the sign-in runs once. Use the command line for real load with a lightweight results writer.

Parameterise what changes

Expose the number of threads, the ramp-up time, the number of iterations and the credentials file location as properties with default values. That lets the same plan run as a one-user proof in the graphical interface and as a large run from the command line without edits.

Remember the heavy listeners

The detailed results viewer you used to verify the once-only behaviour should be disabled before a heavy run, because it stores every request and response in memory and distorts timings at scale.

ActivityBest ModeReason
Placing the controller and childrenGUIVisual tree makes structure obvious
Proving sign-in runs only onceGUI with one userDetailed viewer shows every request
Running two hundred users for an hourCommand lineLower overhead and repeatable
Counting sign-ins afterwardsReport or results fileSample counts confirm placement

20Watching the System Under Test

A controller that changes your traffic pattern also changes what the application experiences, so watch the right metrics.

Authentication service

Expect a burst of load during the ramp-up and quiet afterwards. Watch sign-in rate, response time, token issuance and any rate limiting, especially if the ramp-up is short.

Session storage

Because users keep their sessions for the whole test, the number of live sessions grows to the thread count and stays there. Watch session store memory and size, and expiry behaviour.

Application servers

Steady-state load matches the repeated journey only. Compare processor, memory and connection usage after the ramp-up, when the behaviour is stable.

Database

Sign-in often touches user tables and writes audit records. Expect a short burst of such activity early on, followed by the pattern produced by browsing.

Caches

Each session may populate per-user caches once. The first browsing iteration may therefore be slower than later ones, which is real behaviour worth noticing.

i
Practical Note

Mark the end of the ramp-up on your monitoring dashboards. Conclusions about steady-state performance should be drawn from the period after that marker, when every user has signed in.

21Security Considerations

A step that handles credentials and tokens deserves the same care as any other sensitive part of a test.

Keep credentials out of the plan

Sign-in details belong in a protected data file or in secure run-time properties, never typed into the plan itself, where they would be saved in version control and visible to anyone who opens it.

Use dedicated test accounts

Create accounts used only for testing, with limited permissions. Never run a load test with real customer or employee accounts, and never with an all-powerful administrator account.

Protect tokens in results

Saved request headers, cookies and response bodies may contain live tokens. Store results files securely, restrict who can read them and delete them according to policy.

Expect protective systems to react

A burst of sign-ins during a short ramp-up can trigger rate limiting, bot detection or account lockout. Tell the security team beforehand and agree the window so the test is not mistaken for an attack.

Avoid testing against production by default

Signing in many synthetic users on a live system can send real notifications, write audit logs and affect real users. Prefer an isolated environment unless a production test is formally approved.

!
Common Mistake

Sharing a results file in a public chat or ticket without checking whether it contains tokens or personal data. A token in a pasted line can be used by anyone until it expires.

22Design Patterns That Work

These patterns appear again and again in tidy, trustworthy plans that use one-time steps.

Pattern

Login Once, Browse Many

Sign-in inside the controller at the top, repeated journey below. The simplest and most common arrangement.

Pattern

Copy Identity After Sign-In

Store the signed-in user’s identity in a fresh variable so later data-file reads cannot overwrite it.

Pattern

Guarded Refresh

Combine the one-time sign-in with a conditional refresh for long tests, so tokens are renewed only when needed.

Pattern

Setup for Shared, Once Only for Personal

Use the setUp thread group for test-wide preparation and the Once Only Controller for each user’s own start-up.

Pattern

Fail Fast on Sign-In Errors

Stop a thread whose sign-in failed rather than letting it flood the results with consequent errors.

Pattern

Labelled One-Time Steps

Name one-time samplers clearly so report readers immediately see why their counts are small.

Naming and documentation habits

Give the controller a descriptive name, such as one that says it holds each user’s start-up work, and add a short comment explaining the assumptions: how long the token lives, which setting keeps the session, and where the credentials come from. A plan that is read months later by a colleague, or by you, is far easier to trust when the reasons behind its structure are written next to the elements they explain.

Simple Analogy

A well-run event has a registration desk for each guest and a one-time venue setup for everyone. Keeping those two jobs separate means nobody sets up the whole venue each time a guest arrives.

23Anti-Patterns to Avoid

These mistakes look harmless, and each one quietly spoils results.

ANTI-PATTERN-02 Avoid
Problem

Shared preparation, such as creating a catalogue of test products, is placed inside the Once Only Controller.

Why It’s Harmful

The step runs once per thread, creating hundreds of duplicates, slowing the system and altering the data that later requests rely on.

Correct Approach

Use the setUp thread group for test-wide preparation, and keep the Once Only Controller for each user’s personal start-up only.

ANTI-PATTERN-03 Avoid
Problem

The sign-in once-only design is combined with a setting that clears cookies or resets the user at each iteration.

Why It’s Harmful

Users are effectively signed out after the first iteration, but nothing signs them in again, producing a long run of authorisation failures.

Correct Approach

Keep the same-user option enabled and switch off cookie clearing, or abandon once-only sign-in and sign in on every iteration deliberately.

ANTI-PATTERN-04 Avoid
Problem

The sign-in service’s performance is judged from a once-only sign-in in a browsing test.

Why It’s Harmful

Few samples, a burst shaped by the ramp-up and no sustained load make the numbers unreliable as a measure of capacity.

Correct Approach

Create a dedicated scenario that repeats sign-in at the target rate and measure the service on its own.

ANTI-PATTERN-05 Avoid
Problem

The controller is nested inside random or rotating controllers, or deep inside reusable fragments, with no clear test of its behaviour.

Why It’s Harmful

The one-time step may never run for some users, or may run more often than expected, and nobody notices because skipped steps leave no trace.

Correct Approach

Place it simply under the thread group and verify the sign-in count equals the thread count after every structural change.

ANTI-PATTERN-06 Avoid
Problem

Cleanup steps such as logging out or deleting created data are put inside the Once Only Controller at the end of the plan.

Why It’s Harmful

The controller runs only in the first iteration, so cleanup happens at the very beginning, wiping out the session or data the rest of the journey needs.

Correct Approach

Use the tearDown thread group for test-wide cleanup, and design per-user logout as part of the final iteration through explicit conditions.

24Advantages, Disadvantages and Trade-offs

An honest look at benefits and costs helps you decide when the controller is the right answer.

Advantages

  • Very simple to add and easy to read in the plan tree
  • Makes traffic proportions closer to real sessions
  • Removes the distortion of repeated sign-in from browsing results
  • Reduces unnecessary load on authentication services
  • Needs no scripting and no extra plugins
  • Works identically in graphical and command-line modes

Disadvantages / Trade-offs

  • Counts per thread, which people often mistake for per test
  • Behaviour inside loops can surprise newcomers
  • Skipped steps leave no trace, making bugs hard to notice
  • Cannot refresh expired tokens by itself
  • Gives few samples for one-time steps, weakening their statistics
  • Cannot run a step on the last iteration
i
Balance

The controller is excellent for one simple job and poor at anything cleverer. When your design needs conditions, refresh or test-wide sharing, move to the more suitable element rather than stretching this one.

25Best Practices Checklist

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

1

Decide whose once it is

Per user means this controller; per test means setUp or a total-executions controller.

2

Place it simply

Directly under the thread group, above the repeated steps, unless you have a clear reason otherwise.

3

Protect the session

Keep the same-user setting on, turn off cookie clearing and store tokens in thread variables.

4

Check the clock

Compare the test length with token or session lifetime and add a refresh path if needed.

5

Guard the sign-in

Assert on its result and stop threads that fail to sign in.

6

Prove, then scale

Run one user for several iterations, confirm the sign-in count equals the thread count in a larger run, then raise the load from the command line.

Keep a written test note

For every run, record the thread count, ramp-up time, iteration count or duration, the token lifetime, the credentials source and the number of sign-ins observed. These few lines let anyone reproduce the run and quickly explain odd results later. When two runs disagree, the difference very often hides in one of these settings rather than in the application itself.

!
Common Mistake

Trusting that “it worked in iteration one” means it works. Always inspect at least the third iteration, where every one-time assumption is finally tested.

26Uses Beyond Web Sign-In

The controller works with any sampler, so its usefulness extends well past web pages.

Database connections and session setup

A user-specific preparation statement, such as setting a session option, can run once per thread before the repeated queries begin.

Messaging subscriptions

A consumer subscribes to a topic once and then receives many messages. The subscription step belongs in the once-only part, while receiving belongs in the repeated part.

Raw socket handshakes

Many custom protocols require a greeting or login exchange when a connection opens. That exchange runs once per user, then messages flow repeatedly over the same connection.

Configuration downloads

A mobile or single-page application fetches a configuration file at start-up. Reproducing this once per user matches the real client without inflating the request count.

Terms acceptance and onboarding

First-time screens such as accepting terms or choosing preferences happen once per account in real life, and the controller models that faithfully.

i
Connection Reminder

For protocols that keep a connection per user, make sure the connection is reused across iterations. Otherwise the repeated part will reopen connections and the once-only handshake will be skipped when it is actually needed.

27Real-World Scenarios

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

Seasonal sale preparation

An online retailer prepares for a big sale. Each simulated shopper signs in once through the controller and then browses and buys repeatedly. The team separately runs an aggressive-ramp scenario to examine the sign-in storm at the start of the sale.

Banking dashboard soak test

A bank wants to confirm that its dashboard stays stable for eight hours. The first design used only once-only sign-in, and after thirty minutes most requests failed because sessions expired. The team added a conditional refresh and the soak test then ran cleanly.

Distributed test with shared accounts

A team ran three workers and saw strange authorisation errors. All workers were reading the same first rows of the credentials file, so three threads shared each account. Giving each worker its own account range fixed it.

The missing logout

A tester placed a logout step at the end of the plan inside the controller, believing it would run last. It ran first, killing every session, and the whole run produced errors. Moving cleanup to the tearDown group solved the problem.

Cookie clearing surprise

After switching on a cookie manager option that clears cookies each iteration, a previously healthy test began to fail from the second iteration onward. Turning the option off restored the session between iterations.

Mobile app start-up

A mobile backend team modelled each device’s start-up as a once-only block that downloads configuration and registers the device, followed by repeated data synchronisation. Traffic proportions finally matched their production logs.

28Frequently Asked Questions

Q1Does the controller run once for the whole test or once per user?

Once per user, meaning once per thread in its first iteration. With two hundred threads, the children run two hundred times in total.

Q2Why does my sign-in appear many times in the results?

The controller is most likely inside a Loop Controller or similar element, so it runs on the first iteration of each cycle of that loop. Move it directly under the thread group.

Q3Why do all requests fail after the first iteration?

Usually the session was cleared. Check the same-user option in the thread group and any cookie-clearing option, and confirm the token variable is still filled in later iterations.

Q4Can I use it to run something once for the entire test?

Not reliably. Use the setUp thread group for preparation, or a Throughput Controller in total-executions mode for work that must be counted across all threads.

Q5Can it run something on the last iteration?

No. It only acts on the first iteration. For cleanup, use the tearDown thread group or build explicit conditions for the final iteration.

Q6Does the controller appear as a row in my report?

No. Controllers do not produce samples. You will see rows only for the samplers inside it, unless you wrap them in a Transaction Controller.

Q7What happens if the sign-in fails?

The controller will not retry it, because it only runs in the first iteration. Add assertions and make the thread stop on error, otherwise every later iteration will fail in confusing ways.

Q8Can the sign-in be repeated after a token expires?

Not with this controller alone. Combine a conditional controller with a record of the sign-in time, or use a refresh call, so the plan renews the token when it nears expiry.

Q9How does it behave in distributed tests?

Each worker runs its own threads, and each thread runs the one-time steps once. The total number of executions equals the total thread count across all workers.

Q10Should I measure login performance using this controller?

No. Few samples and a burst shaped by the ramp-up make it a poor basis for capacity conclusions. Build a dedicated scenario that repeats sign-in at the desired rate.

Q11Is it still needed if my application uses long-lived tokens?

It is often a good choice then, because the token stays valid for the whole test. Just confirm the lifetime against the planned duration.

Q12Why do some users share the same account?

The credentials file has too few rows, wraps around, or is identical on several workers. Provide at least one distinct account per thread across the whole test.

Q13Can I nest it inside an If Controller?

You can, but the behaviour becomes harder to reason about. Prefer placing it directly under the thread group and using separate conditional logic elsewhere.

Q14What is the quickest way to verify the placement is right?

Run a short test and compare the number of sign-in samples with the number of threads. If they match, placement is correct. If not, inspect the parent elements.

29Summary and Key Takeaways

The Once Only Controller is a small element with a clear job: run its children in each virtual user’s first iteration and skip them afterwards. Used in the right place, it turns an unrealistic test that signs in again and again into a faithful model of a real session. Used carelessly, it hides failed sign-ins, outlives expiring tokens, multiplies shared work across threads and leaves misleading statistics behind. The remedy is to be clear about whose “once” you mean, to keep the design simple, to protect session state, to prove the behaviour with a few iterations, and to reach for setUp groups, conditional controllers or dedicated scenarios when the problem is bigger than a single start-up step.

Key Takeaways

  • Once per thread — the controller runs its children in each user’s first iteration; it never means once for the whole test.
  • Mind the parent loop — inside a Loop Controller it runs on the first pass of every cycle, so place it directly under the thread group for true once-per-user behaviour.
  • Protect the session — keep the same-user setting on, switch off cookie clearing and store tokens in thread variables so later iterations still work.
  • Watch expiry — match the sign-in strategy to token lifetime and add a refresh path for long tests.
  • Use the right alternative — setUp and tearDown groups for test-wide work, Throughput Controller for counted executions, conditional controllers for refresh.
  • Read statistics carefully — one-time steps have few samples and burst-shaped timing, so do not treat them as steady-state capacity.
  • Verify and stay safe — count sign-ins against threads, test at least three iterations, and keep credentials and tokens out of plans and shared results.