Thread Group in JMeter
The one element that decides how many virtual users hit your application, how fast they arrive, how long they stay, and when they leave. Learn it from zero, and learn it well enough to design real load tests.
Imagine you open a new shop. On opening day, you have no idea how many customers will walk in. Ten? A thousand? What if a thousand people arrive in the same five minutes because a celebrity posted about your shop? Would the doors hold? Would the cashiers keep up? Would the shelves run empty?
Software teams ask the same questions about websites and APIs every day. Instead of waiting for the crowd to arrive and hoping for the best, they send a pretend crowd first. This practice is called load testing, and Apache JMeter is one of the most widely used free tools for it. In JMeter, the pretend crowd is created by one special element called the Thread Group.
If you understand the Thread Group, you understand the heart of every JMeter test. This guide starts with the very basics, explains every setting in plain English, shows how JMeter works inside, and ends with real-world habits that separate a useful load test from a misleading one.
1What Is a Thread Group?
A Thread Group is the starting point of every action in a JMeter test. Nothing runs unless it lives inside one.
The Simple Definition
A Thread Group is a container in JMeter that controls a group of virtual users. Each virtual user runs the same list of steps, such as opening a home page, logging in, searching for a product, and logging out. The Thread Group decides three big things: how many virtual users there are, how quickly they start, and how many times each one repeats the steps.
A thread is the computer’s word for one independent line of work running inside a program. In JMeter, one thread plays the role of one user. If you set a Thread Group to 50 threads, JMeter behaves like 50 people using your application at the same time.
Think of a Thread Group as a casting director for a play. The script is the same for every actor, but the director decides how many actors walk on stage, how many seconds apart they enter, and how many times each actor performs the scene before leaving. The audience, which is your server, sees a crowd of people doing the same job.
Where It Lives
When you open JMeter, you see a tree on the left side. The top item is the Test Plan. A Thread Group is added directly under the Test Plan. Everything else you want to run, such as requests, timers, and checks, is placed under the Thread Group. If a request is not under a Thread Group, JMeter will not run it as part of the load.
A Thread Group is not a request. It does not talk to your server by itself. It only decides who runs the requests, how many of them, and when.
A Quick Word About JMeter
Apache JMeter is an open-source tool written in Java. It was first created to test the performance of a web server product from the Apache family, and over the years it grew to support websites, REST APIs, databases, message queues, and many other systems. It is free, runs on Windows, macOS, and Linux, and has a large community and plug-in ecosystem. Because it is built on Java threads, the Thread Group is the natural way to represent concurrent users.
2Why Thread Groups Exist
To see why we need this element, picture life without it.
The Problem
Testing a website by hand with one browser tells you almost nothing about how it behaves under pressure. A page that loads in one second for a single visitor might take thirty seconds when two thousand visitors arrive together. Servers share a limited amount of memory, processor time, network bandwidth, and database connections. Problems only appear when many users compete for those shared resources.
You cannot hire two thousand people to click buttons at the same moment. You need software that can imitate them. That software needs a way to say, “Create this many users, make them arrive like this, and make them behave like that.” The Thread Group is that way.
What It Gives You
Number of Users
You choose how many virtual users take part, from one to thousands, depending on your machine and test design.
Arrival Pattern
You choose whether everyone arrives at once like a stampede, or gradually like a normal day.
Repetition
You choose how many times each user repeats the journey, or how long they keep going.
Error Behaviour
You choose what happens when something fails: keep going, stop that user, or stop the whole test.
Real-World Motivation
Online retailers such as Amazon-scale stores, ticketing sites, and streaming services all face sudden traffic spikes during sales, concert releases, or new season launches. Teams in those situations rehearse the spike using load-testing tools well before the big day. Whatever tool they use, they must describe the crowd: how many, how fast, how long. In JMeter, that description is written in the Thread Group.
3Core Concepts You Need First
A few words appear again and again in JMeter. Learn them once and the rest becomes easy.
Test Plan
The Test Plan is the whole recipe. It is saved as a file with the extension .jmx. It holds your Thread Groups and everything inside them. Think of it as the full script of the play.
Sampler
A Sampler is one action that sends something to the system under test and measures the answer. The most common one is the HTTP Request sampler, which sends a web request. There are also samplers for databases, FTP, message queues, and more. A sampler is like one line in the script: “go to the login page.”
Virtual User
A virtual user is a pretend person. In JMeter, one thread equals one virtual user. It has its own private memory for variables, its own cookies if you add a Cookie Manager, and its own position in the script.
Iteration
An iteration is one full trip through the steps inside a Thread Group. If a user logs in, browses, and logs out, that is one iteration. If the loop count is five, the user makes that trip five times.
Think Time
Real people do not click instantly. They read, think, and scroll. Think time is the pause between actions, and in JMeter you create it with elements called Timers. Without think time, each virtual user acts like a robot that never rests, which produces much more load than the same number of real people would.
Throughput and Response Time
Response time is how long a request takes to be answered. Throughput is how many requests the system handles in a given time, for example per second. These two numbers, together with the number of users, tell you most of what you need to know about performance.
| Term | Plain Meaning | Where You See It |
|---|---|---|
| Test Plan | The whole saved test | Top of the JMeter tree |
| Thread Group | The crowd controller | Directly under the Test Plan |
| Thread | One virtual user | Number of Threads field |
| Sampler | One action sent to the server | Under a Thread Group |
| Iteration | One full pass through the steps | Loop Count field |
| Timer | A pause that mimics thinking | Under a Thread Group or Sampler |
4Architecture and Where the Thread Group Sits
A JMeter test is a tree. The Thread Group is the trunk from which all the action branches.
Every JMeter test follows the same shape. The Test Plan is the root. Under it, you place one or more Thread Groups. Under each Thread Group, you place the elements that describe what each user does. Some elements apply to everything beneath them, while others apply only to one sampler. This idea is called scope, and the Thread Group is the largest scope you normally work with.
flowchart TD
TP["Test Plan"] --> TG1["Thread Group: Shoppers"]
TP --> TG2["Thread Group: Admins"]
TG1 --> CFG["Config Elements: HTTP Defaults, Cookie Manager, CSV Data Set"]
TG1 --> CTL["Logic Controllers: Loop, If, Transaction"]
CTL --> S1["Sampler: Open Home Page"]
CTL --> S2["Sampler: Search Product"]
CTL --> S3["Sampler: Checkout"]
S2 --> TM["Timer: Think Time"]
S3 --> AS["Assertion: Check Response"]
TG1 --> LS["Listener: Summary and Reports"]
Reading the Diagram
The Test Plan holds two Thread Groups in the picture. One imitates shoppers and the other imitates administrators, because these two kinds of people behave very differently and in very different numbers. Under the shopper group, we see several kinds of helpers.
- Config elements store shared settings, such as the server address, cookies, or a file of test usernames.
- Logic controllers decide the order and conditions of the steps, such as repeating a step or running it only if something is true.
- Samplers are the real requests.
- Timers add think time.
- Assertions check that the answer is correct, not merely fast.
- Listeners collect and show results.
Anything placed directly under a Thread Group applies to every sampler in that group. Anything placed under a single sampler applies only to that sampler. Anything placed under the Test Plan applies to every Thread Group.
Analogy: A Company Org Chart
The Test Plan is the company. Each Thread Group is a department, such as sales or support. The employees in a department follow that department’s rules and use that department’s tools. A rule written for the whole company applies to everybody, while a rule written for one desk applies only to that desk.
5Every Thread Group Setting Explained
The control panel has only a handful of fields. Each one changes your test in an important way.
Name and Comments
The name is only a label for humans, but a good name saves hours. Use names like “Shoppers – Browse and Buy” instead of “Thread Group”. Reports and logs show thread names, so a clear name makes results readable.
Action to Be Taken After a Sampler Error
Sometimes a request fails. This setting tells JMeter what to do next. The usual choices are described below.
Continue
Ignore the error and move to the next step. This is the default and is best for most load tests, because real users also see errors and keep going.
Start Next Thread Loop
Abandon the rest of this iteration and begin the next one. Useful when a failed login makes later steps pointless.
Stop Thread
This one virtual user stops completely. Other users carry on.
Stop Test
The whole test ends gently, letting running requests finish.
Stop Test Now
The whole test ends immediately, even interrupting requests that are in progress.
Number of Threads (Users)
This is the count of virtual users. It is the number most people think of first, but it is only one part of the picture. Fifty threads with no think time can create more pressure than five hundred threads that pause for ten seconds between clicks. Always read this number together with think time and loop settings.
Ramp-Up Period (in Seconds)
The ramp-up period is the time JMeter takes to start all the threads. JMeter spaces the starts evenly. If you have 100 threads and a ramp-up of 50 seconds, JMeter starts about two new threads every second, so the last thread begins roughly at the 50-second mark. If you set the ramp-up to zero, all threads start at nearly the same moment.
Ramp-up is like opening the gates of a football stadium. Opening every gate at once sends the whole crowd rushing in together. Opening them slowly lets people trickle in, and the staff can spot problems early. A sudden rush is a good test of survival, while a gradual flow is a good test of normal operation.
Loop Count
The loop count says how many times each thread repeats its steps. A loop count of one means each user does the journey once and leaves. A loop count of ten means ten times. There is also an Infinite checkbox. With infinite loops, threads never stop on their own, so you must control the end of the test another way, usually with a time limit.
Same User on Each Iteration
This checkbox decides whether a thread keeps its identity between loops. When it is checked, the thread keeps its cookies and session data, so it behaves like one person returning to do more things. When it is unchecked, each iteration starts fresh, like a brand-new visitor. Choose based on what you are imitating: a logged-in user doing many actions, or a stream of different anonymous visitors.
Delay Thread Creation Until Needed
By default, JMeter creates all the thread objects at the beginning, and then each one waits for its start time. For very large tests with a long ramp-up, that wastes memory. If you check this box, JMeter creates each thread only when it is time for it to start. This is a small but useful way to reduce memory use on the test machine.
Specify Thread Lifetime: Duration and Startup Delay
These two fields turn the Thread Group into a timed test.
- Duration (seconds) is how long the Thread Group runs in total. When the time is up, threads stop.
- Startup delay (seconds) is how long JMeter waits before it starts this Thread Group at all. It is helpful when one Thread Group should begin after another has warmed up.
If you set both a loop count and a duration, each thread stops at whichever limit it reaches first.
Choose a ramp-up that makes sense for your duration. If your ramp-up is longer than the time your threads actually live, early threads may finish before late threads even begin, and you will never reach your full user count at the same moment.
6Ramp-Up and Loops with Real Numbers
Numbers make the settings feel real. Let us walk through three small examples.
Example A: A Gentle Morning Rush
You set 60 threads, a ramp-up of 60 seconds, and a loop count of infinite with a duration of 600 seconds. JMeter starts one user per second. After one minute, all 60 users are active. They keep repeating their journey until ten minutes have passed. For the final nine minutes, the load is steady at 60 users. This is a classic steady-state test, great for finding how the system behaves under a constant crowd.
Example B: A Sudden Flash Sale
You set 500 threads, a ramp-up of 5 seconds, and a loop count of 3. JMeter starts about 100 users every second. Within five seconds, all 500 are active, and each will do three trips. This is a spike test. It asks, “What happens if everybody shows up at once?”
Example C: A Single Smoke Check
You set 1 thread, a ramp-up of 1 second, and a loop count of 1. This is not a load test at all. It is a quick check that your script works before you scale it up. Experienced engineers always run this first, because a broken script multiplied by a thousand users only produces a thousand errors.
| Example | Threads | Ramp-Up | Loops or Duration | Test Type |
|---|---|---|---|---|
| A | 60 | 60 s | 600 s duration | Steady load |
| B | 500 | 5 s | 3 loops | Spike |
| C | 1 | 1 s | 1 loop | Smoke check |
Why Ramp-Up Matters to the Server
Servers often need time to wake up. Caches start empty, connection pools open connections slowly, and just-in-time compilers in Java-based servers optimise code only after it runs for a while. A sudden burst at the very first second tests the cold system, which is useful for some goals but misleading for others. A gradual ramp-up lets you see at which user count the response times start to bend upward. That point is often called the knee of the curve, and finding it is one of the main goals of load testing.
When judging results, ignore the ramp-up and early warm-up period. Calculate averages only from the steady part of the test, or the numbers will be pulled around by the start.
7Types of Thread Groups
The standard Thread Group is only the beginning. JMeter and its plug-ins offer several specialised versions.
Thread Group
The everyday choice. Users ramp up in a straight line, run, and then finish. There is no gradual ramp-down.
setUp Thread Group
Runs before the main groups. Use it to prepare things such as creating test data or fetching a token.
tearDown Thread Group
Runs after the main groups finish. Use it to clean up the data your test created.
Open Model Thread Group
Added in newer JMeter versions. You describe the arrival rate of users, such as ten per second, instead of a fixed number of threads.
Ultimate Thread Group
Lets you build a schedule of several rows, each with its own start delay, ramp-up, hold time, and shutdown time. Great for ramp-down and complex shapes.
Concurrency Thread Group
You state a target number of concurrent users and a ramp-up with steps. It works well with a throughput-shaping timer to reach a target request rate.
setUp and tearDown in Plain Words
Imagine a restaurant. Before opening, someone lays out the tables and switches on the ovens. That is setUp. After closing, someone cleans and locks the door. That is tearDown. The main Thread Groups are the actual service in between. In JMeter, setUp groups always run first and tearDown groups run last, no matter where they appear in the tree.
Closed Model versus Open Model
The standard Thread Group follows a closed model. You decide how many users exist, and each user starts a new trip only after finishing the last one. If the server slows down, the users slow down too, so the system gets a bit of breathing room automatically.
Real websites often behave like an open model. People arrive at their own pace whether or not the server is busy. If the server slows down, new visitors keep arriving, and the queue grows. The Open Model Thread Group and some plug-ins exist to imitate that reality.
A closed model is a small restaurant with exactly twenty seats and a waiting rule: a new customer sits only when someone leaves. An open model is a street food stall where new customers keep walking up every minute, no matter how long the line already is. The stall’s line can grow without limit, while the restaurant’s cannot.
8How a Thread Group Works Inside
Understanding the engine room helps you predict how your test will behave and why it sometimes surprises you.
From Tree to Threads
When you press start, JMeter reads your Test Plan tree and hands it to its test engine. The engine finds each enabled Thread Group and prepares to launch it. For every virtual user, JMeter makes a private copy of the elements under the Thread Group. This copying step is called cloning. Because every thread owns its own copy, one user’s variables and counters do not accidentally leak into another user’s.
Each thread then runs as a real Java thread inside the JMeter process. The operating system shares the computer’s processor cores among all these threads, letting each one run in small slices of time. Since most of a load test is spent waiting for network answers, a single machine can often hold hundreds or even a few thousand threads, as long as there is enough memory and the test is designed carefully.
sequenceDiagram
participant U as Tester
participant E as JMeter Engine
participant T as Thread Group
participant V as Virtual User Thread
participant S as Server Under Test
U->>E: Start test
E->>T: Read settings and prepare
T->>V: Start user 1 after ramp-up delay
T->>V: Start user 2 after ramp-up delay
V->>S: Send request from sampler
S-->>V: Send response
V->>V: Run timers and assertions
V->>E: Report sample result
V->>V: Repeat until loops or duration end
E-->>U: Show results in listeners
What Each Thread Owns
- Its own copy of the elements, so each thread has independent state.
- Its own variables, such as a username read from a file or a value pulled out of a previous response.
- Its own cookies and session, if you added a Cookie Manager.
- Its own position in the script and its own loop counter.
Some things are shared across all threads, such as JMeter properties set for the whole run. Sharing needs care, because two threads changing the same shared value can confuse each other.
How the Ramp-Up Is Scheduled
JMeter divides the ramp-up time by the number of threads to find the gap between starts. For 100 threads and a ramp-up of 50 seconds, the gap is half a second. Thread number one starts first, thread two half a second later, and so on. A thread may also pause at the start for a startup delay that you set for the whole group.
How a Thread Ends
A thread ends in one of several ways: it finishes its loop count, it reaches the group’s duration, a sampler error triggers a stop action, or the tester stops the test. A normal stop lets threads finish the request they are working on, while an immediate stop interrupts them. For clean numbers, prefer the gentle stop.
Thread names in JMeter follow a pattern: the Thread Group’s name, a dash, then the thread number. In reports, these names tell you which group and which virtual user produced a result.
9Data Flow and the Life of a Virtual User
Follow one virtual user from birth to retirement and you will understand the whole machine.
flowchart TD
A["Test starts"] --> B["Startup delay if configured"]
B --> C["Thread created at its ramp-up time"]
C --> D["Read data for this user from CSV file"]
D --> E["Run samplers one by one"]
E --> F["Wait for think time between steps"]
F --> G["Check response with assertions"]
G --> H{"Error happened?"}
H -- "No" --> I{"More loops or time left?"}
H -- "Yes" --> J["Apply error action: continue, next loop, stop thread, or stop test"]
J --> I
I -- "Yes" --> D
I -- "No" --> K["Thread ends"]
K --> L["Results collected by listeners"]
Birth
The thread is created at its scheduled moment and receives its own copy of the elements.
Preparation
Config elements supply data. A CSV Data Set, for example, hands this user a username and password.
Action
Samplers fire in order. Each request is timed from the moment it is sent to the moment the answer is complete.
Pause
Timers add think time so the pace looks human.
Judgement
Assertions decide whether the response was truly correct. A fast error page is still a failure.
Repeat or Retire
The thread loops again if work remains. Otherwise it ends and its results remain in the report.
How Test Data Is Shared
The CSV Data Set Config element reads one line from a file for each request round. It has a sharing mode setting that decides who shares the file pointer. In “All threads” mode, the whole test works through the file together, so each line goes to exactly one user. In “Current thread group” mode, each Thread Group walks through the file on its own. In “Current thread” mode, every thread reads the file from the beginning. Picking the wrong mode is a common reason that two users end up logging in with the same account and seeing strange conflicts.
10Choosing the Right Number of Threads
Picking a thread count by guessing is the most common beginner mistake. A little arithmetic does much better.
Start From the Business Goal
Ask what you really want to prove. A good goal sounds like: “Our site must handle 200 completed orders per minute with 95 percent of pages answering within two seconds.” Now you have a target you can turn into numbers.
Little’s Law in Simple Words
There is a famous rule from queueing theory called Little’s Law. It says that the average number of users in a system equals the arrival rate multiplied by the average time each user spends there. In JMeter terms, the number of threads you need equals the number of iterations you want per second multiplied by the time one iteration takes, including think time.
A Worked Example
Suppose your target is 10 complete shopping journeys per second. Each journey takes about 6 seconds, which includes the server’s response time and the think-time pauses. You need roughly 10 x 6 = 60 threads. If the server slows down and each journey takes 12 seconds, the same 60 threads can only produce 5 journeys per second. This shows why a fixed thread count in a closed model does not guarantee a fixed rate.
Think Time and Timers
Timers pause a thread before a sampler runs. Common timers include the Constant Timer, which waits a fixed time, and the Uniform Random Timer, which waits a random time within a range. Random pauses look more natural, because real people do not all wait exactly three seconds. Without any timer, threads fire requests as fast as the server answers, which turns a test of “200 users” into something closer to a test of “thousands of impatient robots.”
Hitting a Target Rate
When you care about requests per minute instead of users, JMeter offers throughput-focused helpers. The Constant Throughput Timer and the Precise Throughput Timer slow threads down so that the overall request rate stays near your target. They pair well with a slightly generous thread count, so threads are available to reach the rate even when the server gets slower.
Do not confuse registered users, daily visitors, concurrent users, and requests per second. A site with one million visitors per day might only see a few hundred users at the same instant. Always convert business numbers into concurrency before choosing the thread count.
11Using More Than One Thread Group
Real traffic is a mixture. Different groups of people do different things in different numbers.
Why Split Into Several Groups
An online store has browsers, buyers, and a few administrators. Browsers are numerous and light. Buyers are fewer but cause heavier work, such as payments. Administrators are rare but run expensive reports. If you put them all in one Thread Group, you cannot control their numbers separately. With one group per kind of user, you can say, “Give me 400 browsers, 50 buyers, and 5 admins,” and watch how they affect each other.
Run Together or One After Another
By default, JMeter starts all enabled Thread Groups at the same time. They run in parallel, which is exactly what you want to imitate a real mixture of users. The Test Plan has a checkbox named “Run Thread Groups consecutively.” When checked, JMeter runs one group, waits for it to finish, and then starts the next. This is handy when you want to test each user type in isolation.
Parallel Groups
- Imitates real mixed traffic
- Reveals competition for shared resources
- Saves total test time
Consecutive Groups
- Easier to read results for one user type
- Does not show how groups hurt each other
- Takes longer overall
Using the Startup Delay to Stagger Groups
A neat trick is to give different groups different startup delays. For example, let the browser group begin right away to warm up caches, and let the buyer group start two minutes later. This creates a more realistic ramp, where background traffic is already present when the important flow begins.
Variables Do Not Cross Groups Freely
Each Thread Group has its own threads and its own thread-local variables. A value found by a thread in one group is not automatically visible to threads in another group. If you must pass something across groups, such as a token fetched once for everybody, the usual approach is to fetch it in a setUp Thread Group and store it as a shared property.
12Distributed Testing and Thread Groups
One computer can only generate so much load. When you need more, you add helpers, and the Thread Group behaves in a way that surprises many people.
The Controller and the Workers
In JMeter’s distributed mode, one machine acts as the controller and several others act as workers, historically called slaves. The controller sends the Test Plan to every worker. Each worker then runs the plan on its own and sends results back.
flowchart LR
C["Controller Machine"] --> W1["Worker 1: 100 threads"]
C --> W2["Worker 2: 100 threads"]
C --> W3["Worker 3: 100 threads"]
W1 --> LB["Load Balancer"]
W2 --> LB
W3 --> LB
LB --> A1["App Server 1"]
LB --> A2["App Server 2"]
A1 --> DB["Database"]
A2 --> DB
W1 -. "results" .-> C
W2 -. "results" .-> C
W3 -. "results" .-> C
The Multiplication Surprise
Every worker runs the whole Thread Group exactly as written. If your Thread Group says 100 threads and you use three workers, the server sees 300 users, not 100. Many beginners accidentally triple or quintuple their load by forgetting this. The fix is simple: divide your target thread count by the number of workers when you set the number of threads.
Before blaming the application for poor results, check that the load generator is healthy. If a worker’s processor is nearly full or its memory is exhausted, your numbers reflect the test machine’s trouble, not the server’s.
Alternatives to Classic Distributed Mode
Many teams today run JMeter workers inside containers on orchestration platforms, or use cloud load-testing services that run JMeter scripts at scale. The Thread Group rules are the same in all of these. Only the machinery that launches the workers changes.
13Performance and Scalability of the Test Machine
Your load generator is a computer too. If it struggles, your results lie.
What Limits a Single Machine
Every thread costs memory. It also costs a little processor time each time it builds a request, reads a response, and records a result. When you add scripting, response parsing, and many listeners, the cost per thread rises quickly. The three usual limits are the following.
- Memory. JMeter runs inside a Java virtual machine with a maximum heap size. If the heap fills up, the test slows down or crashes with out-of-memory errors. You can raise the heap size when you launch JMeter.
- Processor. Heavy scripts, encryption for secure connections, and large response bodies use processor time. If the processor is saturated, requests are sent late, which hides the real behaviour of your server.
- Network. A test machine on a slow or shared connection can become the bottleneck. Large downloads can fill the network before the server feels any strain.
Run in Non-GUI Mode for Real Tests
JMeter has a graphical window that is perfect for building and debugging a script with a few users. For real load, run JMeter from the command line without the window, which is called non-GUI mode. The window itself uses memory and processor time and can distort results. After the run, JMeter can produce an HTML report with charts from the saved results file.
Keep Listeners Light
Listeners that keep every request and response in memory, such as the View Results Tree, are wonderful for debugging and terrible for load. During a real run, disable them and write raw results to a file instead. You can view charts and tables afterwards.
Scale Up, Then Out
First make the script efficient and give JMeter enough heap and processor. Then, if one machine still cannot produce the target load, add more machines using distributed mode or containers. As a rule of thumb, scale out before the generator’s processor stays above about 75 percent for long periods.
14Monitoring, Logging, and Metrics
A load test creates pressure. Monitoring tells you what the pressure did.
The Numbers JMeter Reports
| Metric | What It Tells You | Why It Matters |
|---|---|---|
| Average response time | The mean time for requests | Quick view, but can hide bad outliers |
| Percentiles (90th, 95th, 99th) | The time under which most requests finish | Shows what the unlucky users experience |
| Throughput | Requests handled per second or minute | Shows capacity |
| Error percentage | Share of failed requests | Shows stability under load |
| Active threads over time | How many users were running | Confirms the Thread Group did what you planned |
| Connect time and latency | Where time is spent | Separates network delay from server work |
Imagine ninety-nine requests take one second and one takes one hundred seconds. The average looks like two seconds, yet one customer waited more than a minute and a half. Percentiles reveal that hidden pain, which is why experienced testers rely on them.
Watch the Server Side Too
JMeter measures what the client sees. To find the cause of slowness, you also need numbers from the server: processor usage, memory, disk activity, database connections, queue lengths, and application logs. Plug-ins and external monitoring tools can collect these while the test runs, and you can line up both views on the same timeline.
Live Dashboards
Teams commonly stream JMeter results during a run to a time-series database using the Backend Listener. A dashboard tool such as Grafana can then draw live charts of response times, throughput, and errors. This is helpful for long tests because you can spot trouble within seconds instead of waiting for the final report.
Logging
JMeter writes its own log file with information about the test engine, errors, and warnings. Sampler results can be saved to a results file, which is commonly a comma-separated file with one row per request. Keep the settings of each run, such as the thread count and ramp-up, in your notes next to the results. A chart without its settings is hard to trust a month later.
15Security and Safety
A Thread Group is a tool that can hurt systems if misused. Treat it with respect.
Only Test Systems You Are Allowed To Test
Sending a flood of requests to a system you do not own, or do not have written permission to test, may be illegal and can be treated like an attack. Even inside your own company, warn operations teams and anyone who shares the environment before you start. Cloud providers and hosting companies often have their own rules about load and stress testing, so read them first.
Protect Test Data and Credentials
- Do not store real customer data in test files. Use fake accounts or masked data.
- Keep passwords and tokens out of shared test plan files. Load them from protected files or environment settings.
- Do not upload result files with sensitive responses to public places.
Secure the Load Generators
In distributed mode, the controller and workers talk over a network. Keep that network private, use the encryption options that recent JMeter versions support for this traffic, and keep JMeter itself up to date, because older versions had weaknesses in their remote-control features. Never expose worker ports to the open internet.
Expect Defences to Fight Back
A well-defended production system includes web application firewalls, rate limiters, and bot detection. These may block or slow your virtual users, because from their point of view a thousand identical clients really do look suspicious. Plan with the security team to allow your test traffic, or test in an environment that mirrors production without those blocks, and be clear about which of the two you did when you report results.
A test that writes data, such as placing orders or sending emails, can leave real side effects. Point it at a test environment, use test payment settings, and clean up with a tearDown Thread Group.
16Advantages, Disadvantages, and Trade-Offs
Every design has strengths and weaknesses. Knowing both keeps you from using the Thread Group in the wrong place.
Advantages
- Simple settings: users, ramp-up, loops, and duration
- Each virtual user is isolated with its own variables
- Several groups can model different user types
- Works with a huge range of protocols through samplers
- Free, open source, and extendable with plug-ins
- Scales out with distributed mode or containers
Disadvantages
- One thread per user uses a lot of memory at very large scale
- The standard group uses a closed model and lacks a ramp-down
- Fixed thread counts do not guarantee a fixed request rate
- Complex shapes need plug-ins or the newer open-model group
- A heavy script can overload the test machine
- Results can be misleading if think time is ignored
Key Trade-Offs
| Choice | One Side | Other Side |
|---|---|---|
| Short ramp-up or long ramp-up | Tests spikes and cold systems | Shows the gradual knee of the curve |
| Few heavy threads or many light threads | Easier to run, less realistic | More realistic, needs more memory |
| Closed or open model | Simple and safe for the server | More faithful to internet traffic |
| Realistic think time or none | Honest user numbers | Pure stress on the server |
| One group or many groups | Simple to build | Better mix of behaviour |
17Design Patterns and Anti-Patterns
Experienced testers keep returning to a few shapes that work and a few traps that fail.
Patterns That Work
Smoke, Then Scale
Run one user first to prove the script works. Then raise the load in careful steps.
Step Load
Add users in stages, hold each stage, and watch for the stage where times begin to climb.
Soak Test
Run a moderate steady load for hours to find memory leaks and slow decay.
Spike Test
Jump suddenly to a high load and then drop back, to see how the system copes and recovers.
Workload Mix
Use one Thread Group per kind of user, with numbers copied from real traffic data.
Setup and Cleanup
Use setUp and tearDown groups to prepare data and tidy up so each run starts clean.
Traps to Avoid
What It Looks Like
The tester sets thousands of threads, no timers, and a ramp-up of zero, then declares that the site “cannot handle ten thousand users.”
Why It Hurts
With no think time, each thread behaves like many real people. The test measures something no real crowd would ever do, so the conclusion is useless and may push the team to spend money fixing a problem that does not exist.
Better Approach
Calculate the thread count from the business goal, add realistic think time, and ramp up in steps.
What It Looks Like
The tester runs the test from the graphical window with the View Results Tree turned on and then trusts the numbers.
Why It Hurts
The window and the heavy listener eat memory and processor time. The test machine becomes the slowest part, and the reported response times include its own delays.
Better Approach
Debug with a few users in the window, then run in non-GUI mode with listeners off and results saved to a file.
What It Looks Like
Every virtual user logs in with the same single account, or reads the same product, or uses the same search term.
Why It Hurts
Caches serve the same answer again and again, so the server looks much faster than it will be with real, varied traffic. Shared accounts may also lock or conflict.
Better Approach
Feed each thread different data from a CSV file and choose the sharing mode carefully.
18Best Practices and Common Mistakes
Habits that save time and trust.
Best Practices
Write the Goal First
Decide what you want to prove, with numbers for users, response times, and error limits, before touching JMeter.
Name Everything Clearly
Give Thread Groups and samplers names that a stranger can understand in a report.
Use Realistic Think Time
Add random timers so users pause like humans.
Check Responses with Assertions
A fast error page is not a success. Confirm the content is right.
Ramp Up and Warm Up
Use enough ramp-up time and ignore the warm-up period when computing results.
Watch the Load Generator
Keep an eye on its processor, memory, and network so you know the test is trustworthy.
Repeat the Test
Run the same test more than once. A single run can be a fluke.
Common Mistakes at a Glance
| Mistake | Result | Fix |
|---|---|---|
| Ramp-up longer than thread lifetime | Full load is never reached | Shorten ramp-up or extend the duration |
| Forgetting that each worker runs the full group | Load is multiplied | Divide threads by the number of workers |
| No cookie handling | Sessions break, logins fail | Add a Cookie Manager |
| Reusing one test account | Cache effects and conflicts | Use a data file with many accounts |
| Reading averages only | Hidden slow requests | Study percentiles and error rates |
| Testing against a tiny environment | Results do not predict production | Use an environment close to production |
19Real-World Examples
These scenarios show how the Thread Group settings change with the goal. They describe how teams at well-known kinds of companies commonly think, and they are illustrations, not claims about any one company’s private tools.
A Retail Giant Preparing for a Big Sale
A very large online retailer expects sales traffic to jump within minutes of a sale starting. The test team builds separate Thread Groups for browsers, searchers, and buyers, sets a short ramp-up for the spike scenario, and a long steady phase to watch for slow memory growth. They run the spike scenario several times and tune the system until the 95th percentile stays inside the limit.
A Streaming Service Before a Big Release
A video streaming company expects a huge number of people to open the app within the same hour when a popular series is released. A Thread Group imitates the login and home screen flow, which is the part that every viewer must pass through, with a step load that raises the user count in stages. The goal is to learn at which stage the sign-in service begins to slow.
A Ride-Hailing Platform on a Rainy Evening
A ride-hailing company knows that rain causes many people to open the app and request rides at once. Because those users arrive at their own pace, an open-model style test, with an arrival rate instead of a fixed user count, matches reality better. It shows whether the matching service falls behind when requests pile up.
A Bank Checking Its Nightly Window
A bank wants to know if its payment API stays healthy during a four-hour soak. A modest steady Thread Group runs with realistic think time and assertions that check each payment status. The tester looks for slow growth in response times, a sign of a leak, and for errors that appear only after hours of running.
A Small Team Before Launch
A start-up with a single web server uses a Thread Group of fifty users, a one-minute ramp-up, and a ten-minute duration. The result shows that the database runs out of connections at around forty users, a problem that took one hour to fix and would have embarrassed them on launch day.
20Building Your First Thread Group Step by Step
Reading about settings is useful, but building one yourself makes everything click. Here is the path an experienced engineer follows on the very first day.
Open a Fresh Test Plan
Start JMeter and look at the empty tree on the left. The Test Plan is already there. Give it a meaningful name, such as the name of the application you are testing, and save the file straight away so you never lose work.
Add a Thread Group
Right-click the Test Plan, choose Add, then Threads (Users), then Thread Group. A new branch appears in the tree. Click it and the settings panel opens on the right.
Start With Tiny Numbers
Set the number of threads to one, the ramp-up to one second, and the loop count to one. You are not testing load yet. You are testing your own script, and a single user is the cheapest way to find mistakes.
Add Shared Settings
Under the Thread Group, add an HTTP Request Defaults element to hold the server name once, and a Cookie Manager so sessions work. These two small helpers prevent a great many beginner problems.
Add a Sampler
Add one HTTP Request sampler for a simple page, such as the home page of a test environment you own. Keep it plain: a single page, no login yet.
Add a Listener for Debugging
Add the View Results Tree listener. Remember, this is only for the one-user smoke run. It lets you see the exact request and response so you can confirm the script does what you think it does.
Run and Read
Press the green start button. Look at the result. A green tick means the request succeeded, and a red cross means it failed. Open the response data and confirm the page content is what you expected.
Grow Slowly
Raise the thread count to five, then ten, then twenty-five, always with a sensible ramp-up. At each step, check the error percentage and response times. Stop growing when you see the first sign of trouble, and write down the number.
Switch to a Real Run
Before the serious run, turn off or remove debugging listeners, add think time, and run from the command line without the window. Save the results to a file for later study.
Keep a small notebook, or a text file, of each run: date, thread count, ramp-up, duration, and result. After a few weeks, this simple log becomes a trusted history that shows whether your system is getting faster or slower.
21A Complete Workload Model for an Online Store
Let us design a realistic test from business numbers all the way to Thread Group settings. This is the kind of reasoning that interviewers love to hear.
Step 1: Collect the Business Facts
Imagine an online store. Its analytics show that at the busiest hour of the busiest day, about 6,000 visitors start a shopping session. The average session lasts about five minutes. Of all visitors, roughly seventy percent only browse pages, twenty-five percent search for products and fill a basket, and five percent complete a purchase.
Step 2: Convert to Concurrency
First, turn 6,000 sessions per hour into sessions per second. That is 6,000 divided by 3,600, which is about 1.67 new sessions per second. Each session lasts about 300 seconds. Using Little’s Law, the number of people on the site at the same moment is 1.67 multiplied by 300, which gives roughly 500 concurrent users.
Step 3: Split by Behaviour
| Thread Group | Share of Users | Threads | What They Do |
|---|---|---|---|
| Browsers | 70 percent | 350 | Home page, category pages, product pages |
| Searchers and Basket Builders | 25 percent | 125 | Search, filter, add to basket |
| Buyers | 5 percent | 25 | Login, basket, payment, confirmation |
The three groups add up to 500 threads, which matches the concurrency we calculated. Each group has its own script, its own think time, and its own data file.
Step 4: Choose the Shape of Time
A good plan has three phases. First, a ramp-up of ten minutes lets the system warm up and shows where response times begin to climb. Second, a steady phase of thirty minutes holds the target load so you can measure stable behaviour. Third, a short ramp-down, if you use a plug-in group that supports it, lets you see how the system recovers.
Step 5: Add a Safety Margin
Real businesses plan for growth and surprises. Run the same model at 120 percent and 150 percent of today’s peak. If the system survives 150 percent with healthy response times, the team has a comfortable safety margin. If it breaks at 110 percent, the team knows exactly how much room remains.
Step 6: Define Pass or Fail in Advance
Before running anything, write down what success means. For example: the 95th percentile of every page stays under two seconds, the error percentage stays under one percent, and the processor on the application servers stays under seventy percent. Writing these rules first protects you from the human habit of shifting the goalposts after seeing the results.
When asked how you would size a load test, walk through this exact flow: business numbers, then sessions per second, then Little’s Law, then a split by user type, then time shape, then safety margin, then pass and fail rules. It shows structured thinking, not guesswork.
22Advanced Load Shapes and Special Thread Groups
The standard group draws a simple ramp. Real tests often need curves, plateaus, and falling lines.
Ultimate Thread Group: A Schedule You Draw
The Ultimate Thread Group lets you add several rows to a table, and each row is a wave of users. Every row has five values: how many threads to start, how long to wait before this row begins, how many seconds to take to start those threads, how long to hold the load, and how many seconds to take to shut them down. Overlapping several rows lets you build a staircase, a hill, or a double peak.
Think of a concert venue with several entrances. Row one is the early crowd that arrives, stays, and leaves slowly. Row two is the big crowd that pours in later and leaves all at once. Together they draw the real shape of the evening, which no single straight line can describe.
Concurrency Thread Group: Aim for a Number
The Concurrency Thread Group asks a different question. Instead of “how many threads in total,” it asks, “how many users should be active at the same time?” You give it a target concurrency, a ramp-up time, the number of ramp-up steps, and a hold time. During the run, it keeps the active user count near the target by starting new threads when others finish. This is much closer to how people think about load in the real world.
Throughput Shaping Timer: Aim for a Rate
Sometimes the business cares about requests per second, not users. The Throughput Shaping Timer lets you write a schedule of target rates, such as starting at ten requests per second and climbing to a hundred over five minutes. It works hand in hand with the Concurrency Thread Group, which supplies enough threads to reach that rate. If the server slows down, the pair adds more threads, which behaves a bit like an open model.
Open Model Thread Group: Arrivals Instead of Threads
The Open Model Thread Group, available in newer JMeter versions, takes a schedule that describes how fast users arrive and how long to pause. You might say, in words, “arrive at ten users per second for five minutes, pause for one minute, then arrive at twenty per second for ten minutes.” JMeter creates threads as needed to keep that arrival rate. It is a great fit for public websites, where visitors do not wait for each other.
| You Want To Say | Best Fit |
|---|---|
| “Run fifty users for ten minutes” | Standard Thread Group |
| “Build a hill with a slow rise and a fast fall” | Ultimate Thread Group |
| “Keep two hundred users active in steps” | Concurrency Thread Group |
| “Hit exactly this many requests per second” | Concurrency Thread Group with Throughput Shaping Timer |
| “Visitors arrive at this rate no matter what” | Open Model Thread Group |
Plug-in groups are installed separately, usually through the JMeter Plugins Manager. If you share a test file with teammates, make sure they have the same plug-ins installed, or the file will open with missing elements.
23Thread Groups in Automation and Pipelines
Modern teams do not run performance tests only once before launch. They run them again and again, as part of everyday engineering.
Why Automate
A system that was fast last month can become slow after a few small code changes. Nobody notices, because each change looks harmless. Running a short performance test on every important change, or every night, catches slow drift early, when the fix is cheap and the cause is still fresh in the team’s mind.
Parameterise the Thread Group
For automation, avoid typing fixed numbers into the Thread Group. Instead, let the number of threads, the ramp-up, and the duration come from named properties that can be set from the command line when JMeter starts. Each property can have a sensible default so the test still works when you open it by hand. This way, the same test file can run as a tiny smoke check on every code change, a medium check every night, and a heavy test before a major release.
A Typical Pipeline Flow
Deploy to a Test Environment
The pipeline builds the application and deploys it to an environment that looks like production.
Run a Short Smoke Load
JMeter runs in non-GUI mode with a few users for a couple of minutes, just to prove the main flows work.
Check Against Thresholds
A script reads the results file and compares the percentiles and error percentage with the limits that the team agreed on.
Pass or Fail the Build
If the limits are broken, the pipeline stops and notifies the team, just like a failing unit test.
Publish the Report
The HTML report and the raw results are stored with the build, so anyone can compare today with last week.
Helpful Companions
Teams often combine JMeter with a continuous integration server, such as Jenkins, and with wrapper tools that read simple configuration files and apply pass or fail rules. Version control keeps the test files history, and code review applies to test files just as it does to application code.
Short pipeline tests are not a replacement for a full load test. They detect large regressions quickly, while the long, heavy test still belongs before major releases and big events.
24Troubleshooting Guide
When a test misbehaves, the cause is almost always one of a small set of familiar suspects.
| Symptom | Likely Cause | What To Do |
|---|---|---|
| Fewer active users than planned | Ramp-up too long, loop count too low, or an error action that stops threads | Check the active threads chart and adjust the Thread Group settings |
| Test ends much earlier than expected | Loop count finished before the duration was reached | Use infinite loops with a duration for timed tests |
| Out-of-memory errors | Too many threads or heavy listeners for the memory given | Raise the heap, remove listeners, or add workers |
| Many connection errors from the test machine | The machine ran out of network ports or file handles | Reuse connections, tune the operating system limits, or add machines |
| Everyone logs in as the same user | Data file sharing mode or missing data setup | Review the CSV Data Set Config and its sharing mode |
| All requests fail with the same error | Script problem, expired token, or a firewall blocking the traffic | Run with one user and read the response in the debugging listener |
| Response times look too good | Caching, same data for all users, or no assertions | Vary the data and check the response content |
| Results swing wildly between runs | Shared environment, noisy neighbours, or unstable test machine | Isolate the environment and watch the load generator health |
| Load is higher than expected in distributed mode | Every worker runs the whole Thread Group | Divide the thread count by the number of workers |
A Simple Debugging Routine
When something looks wrong, shrink the problem. Reduce the Thread Group to one user and one loop. Turn on the debugging listener. Run once and read the actual request and response. Fix the script first, and only then grow the load again. Almost every mystery shrinks when you look at a single user.
If a big orchestra sounds wrong, a good conductor does not ask all one hundred players to play louder. The conductor asks one musician at a time to play alone and listens for the wrong note. Debugging a Thread Group works the same way.
25Sizing the Load Generator in Detail
How many threads fit on one machine? There is no single answer, but there is a method to find yours.
The Pilot Run Method
Do not guess. Measure. Run your real script with a modest number of threads, say fifty, for a few minutes. Watch the processor and memory of the test machine while it runs. Then double the threads and run again. Keep doubling until the processor stays above about seventy-five percent or the memory gets uncomfortably full. The last comfortable number is the safe size for this machine and this script.
What Drives the Cost Per Thread
- Size of responses. Large pages and file downloads cost memory and network.
- Secure connections. Encryption adds processor work, especially when each user opens a new connection.
- Scripting and extraction. Searching big responses for values costs time, and complex scripts cost more.
- Listeners. Anything that stores or draws results while running adds cost.
- Think time. Long pauses reduce work per thread, so more threads fit on one machine.
- Java thread stack space. Each thread reserves some memory for its own call stack, so thousands of threads add up even when they mostly wait.
Give JMeter Enough Memory
JMeter starts with a modest default heap, on the order of one gigabyte in many versions. For large tests, raise the maximum heap, but keep it below the total memory of the machine so the operating system does not start swapping to disk, which would wreck your timings. As a guide, leave at least a quarter of the memory free for the system itself.
Keep Clocks and Networks Honest
If you use several workers, make sure their clocks are in sync, because timestamps from different machines will be merged into one report. Place the generators close to the target in network terms when you want to measure the server, and place them in different regions when you want to measure what faraway users really experience.
26How Timers, Controllers, and Config Elements Work With a Thread Group
A Thread Group on its own is only a crowd. The helpers placed under it decide what that crowd actually does.
Logic Controllers: The Traffic Directors
A logic controller decides the order and conditions of the steps a thread follows. Think of a thread as a visitor walking through a building, and the controller as the signs that say, “go through this door five times,” or “take this corridor only if the shop is open.”
- The Loop Controller repeats the steps inside it a set number of times. This is different from the Thread Group’s loop count, because it repeats only a part of the journey, such as “view three products,” while the Thread Group loop repeats the whole journey.
- The If Controller runs its steps only when a condition is true, such as when a login succeeded.
- The Transaction Controller groups several requests into one named step, so that reports show one number for “Checkout” instead of ten separate lines.
- The Random Controller picks one of its children each time a thread passes through, which is a simple way to imitate people choosing different pages.
- The Throughput Controller runs its steps for only a chosen percentage of the iterations. It is a handy way to say that only five percent of users buy something.
The Throughput Controller, which chooses how often steps run, is a different thing from the Constant Throughput Timer, which slows threads to hit a request rate. The names are similar, but their jobs are not.
Timers: The Pace Setters
Timers run before each sampler in their scope. When a timer is placed directly under the Thread Group, it applies to every sampler in the group. When it is placed under one sampler, it affects that sampler only. A common mistake is to add a timer under the Test Plan by accident and then wonder why every group is slow. Always check the position of the timer in the tree.
Config Elements: The Shared Notebooks
Config elements hold information that many samplers need. The HTTP Request Defaults element stores the server name and port. The HTTP Header Manager stores headers such as the content type. The Cookie Manager stores cookies per thread. The CSV Data Set Config feeds each thread with values from a file. Because these live inside the Thread Group, each group can have its own settings, such as a different server for administrators.
Pre-Processors and Post-Processors
A pre-processor runs just before a sampler and can prepare something, such as building a value for the request. A post-processor runs just after a sampler and can pull values out of the response, such as a session token or an order number, to be used by later steps. Because these values are stored in each thread’s own variables, one user’s token never leaks into another user’s request.
Assertions: The Quality Inspectors
An assertion checks the answer. A Response Assertion can confirm that a page contains a certain text. A Duration Assertion can mark a request as failed if it took longer than allowed. Without assertions, a server that quickly returns an error page would look wonderful in your report, so every serious test needs at least a few.
The Order of Execution
For each sampler, JMeter follows a fixed order inside the thread. Config elements are applied first, then pre-processors, then timers, then the sampler runs, then post-processors, then assertions, and finally listeners record the result. Remembering this order explains many surprises, such as why a timer delays the sampler that follows it rather than the one before it.
| Order | Element | Purpose |
|---|---|---|
| 1 | Config elements | Supply shared settings and data |
| 2 | Pre-processors | Prepare the request |
| 3 | Timers | Wait before sending |
| 4 | Sampler | Send the request and measure the answer |
| 5 | Post-processors | Extract values from the response |
| 6 | Assertions | Judge whether the answer was correct |
| 7 | Listeners | Record and show the result |
Picture a cashier serving one customer. First the cashier looks at the shop rules and price list, which are the config elements. Then the cashier prepares the till, which is the pre-processor. Then the cashier waits for the customer to finish choosing, which is the timer. The sale happens, which is the sampler. The cashier reads the receipt number, which is the post-processor, checks that the money is right, which is the assertion, and writes it in the day’s book, which is the listener.
27A Case Study: The Test That Lied
This story is a composite of problems that engineering teams commonly meet. It shows how small Thread Group choices lead to big wrong conclusions.
The Situation
A team is about to launch a new mobile app backend. The business expects two thousand users at the same time on launch day. A junior engineer builds a JMeter test with a single Thread Group of two thousand threads, a ramp-up of ten seconds, an infinite loop, no timers, and one account for every user. The test runs from a laptop, with the graphical window open and the View Results Tree turned on.
What the Test Reported
After a minute, the results look terrible. Response times climb past thirty seconds. More than half the requests fail. The engineer reports that the backend cannot handle even half of the expected load, and the launch is put in doubt.
What Was Really Wrong
The Laptop Was the Bottleneck
The laptop ran out of memory because of the window and the heavy listener, and its processor was almost fully busy. Requests were delayed on the client side before they even left the machine.
No Think Time
With no timers, each of the two thousand threads fired a new request the instant the last one finished. Real users take several seconds between actions, so the test created a load many times higher than two thousand real people would.
One Shared Account
Every user logged in with the same account. The backend, quite sensibly, protected that account from suspicious repeated logins and started rejecting requests, which counted as failures.
A Ten-Second Stampede
Two thousand users started within ten seconds, which is a spike and not an ordinary launch pattern. The system was tested for a sudden shock but judged as if it had been tested for steady traffic.
How the Team Fixed the Test
A senior engineer rebuilt the test with care. The thread count was calculated from the business goal. A ten-minute ramp-up was used, followed by a thirty-minute steady phase. Random timers of two to eight seconds were added to imitate thinking. A data file supplied thousands of different test accounts. Assertions checked that responses contained the expected content. The test ran from two cloud machines in non-GUI mode, with the generators’ processor and memory watched all the time.
The New Result
With a fair test, the backend handled the expected load comfortably, and the 95th percentile of response times stayed under two seconds. A real weakness did appear, though: the database ran short of connections at about one and a half times the expected load, which gave the team a clear, early, fixable finding.
A badly designed test can make a healthy system look sick, and it can also make a sick system look healthy. The Thread Group settings, the think time, the data, and the test machine all matter. Trust a result only after you have checked each of them.
28Glossary of Terms
Keep this page handy. Every word here appears somewhere in the guide.
| Term | Plain Meaning |
|---|---|
| Assertion | A check that decides whether a response was correct |
| Closed model | A fixed number of users, where each starts a new trip only after finishing the last one |
| Concurrency | How many users are active at the same moment |
| Controller | The machine that sends the test plan to workers in distributed mode |
| Iteration | One full pass through the steps inside a Thread Group |
| Knee of the curve | The load level where response times start to rise sharply |
| Listener | An element that records or shows results |
| Little’s Law | Users in the system equal arrival rate multiplied by time spent in the system |
| Non-GUI mode | Running JMeter from the command line without the window, used for real load |
| Open model | Users arrive at a set rate regardless of how busy the server is |
| Percentile | The time under which a given share of requests finished |
| Ramp-up | The time JMeter takes to start all threads |
| Sampler | An element that sends a request and measures the answer |
| Soak test | A long test with steady load to find slow leaks |
| Spike test | A test with a sudden jump in load |
| Steady state | The stable part of a test after ramp-up |
| Think time | The pause a real person takes between actions |
| Thread | One virtual user in JMeter |
| Throughput | How many requests are handled per unit of time |
| Worker | A machine that runs the test plan under the control of a controller |
29Settings That Beginners Often Confuse
Many wrong results come from mixing up two things that sound alike. Here are the most common pairs, explained side by side.
Threads, Users, and Concurrent Users
A thread is a technical object inside JMeter. A virtual user is the role that the thread plays. A concurrent user is a user who is active at the same moment as others. If a thread sleeps for most of its time because of think time, it is still a user in the system, even though the server is not busy with it every second. When a manager says “two thousand users,” always ask whether that means registered accounts, daily visitors, or people active at the same moment. These are very different numbers, and only the last one maps closely to a thread count.
Ramp-Up Period and Think Time
Ramp-up controls when threads start. Think time controls how long each thread pauses between actions after it has started. Ramp-up happens once at the beginning of the Thread Group. Think time happens again and again during the whole life of every thread. Making the ramp-up long does not make users act slower, and adding think time does not make users arrive slower.
Loop Count and Loop Controller
The Thread Group’s loop count repeats the entire set of steps under the group. A Loop Controller repeats only the steps inside it. If you want users to log in once and then view ten products, put the login before a Loop Controller and the product page inside it, and set the Thread Group loop count to one. If you put the login inside the repeated part by mistake, every iteration logs in again, which creates a very different load on the login service.
Duration and Startup Delay
Duration tells the group how long it may run. Startup delay tells the group how long to wait before it begins. The delay is not part of the duration. A group with a delay of 120 seconds and a duration of 600 seconds begins at the two-minute mark and ends at the twelve-minute mark of the whole test.
Stop Thread and Stop Test
Stop Thread ends one virtual user, and the others keep working. Stop Test ends everything. Using Stop Test in a load test is risky, because one unlucky failure can end an hour of careful work. Use it only during early debugging, or when a failure truly makes all further testing pointless, such as when the target server is unreachable.
Constant Timer and Constant Throughput Timer
The Constant Timer adds a fixed pause. The Constant Throughput Timer does not add a fixed pause. It calculates how long to wait so that the overall request rate stays near a target. The first is about the pause between actions, and the second is about the total rate of work. Since the second one only slows threads down, it cannot make a slow system go faster, and it cannot create extra load unless there are enough threads to supply it.
Samples, Requests, and Transactions
A sample is one measured action by a sampler. In a web test, a sample usually equals one request. A transaction, when you use a Transaction Controller, groups several samples into one business step. If you report on samples, a single page with many embedded files may produce many lines. If you report on transactions, you see one line per business step, which is far easier for managers to read.
| Pair | First Meaning | Second Meaning |
|---|---|---|
| Ramp-up and think time | When threads start, once | How long threads pause, repeatedly |
| Loop count and Loop Controller | Repeats the whole journey | Repeats part of the journey |
| Duration and startup delay | How long the group runs | How long it waits before starting |
| Stop Thread and Stop Test | Ends one user | Ends the whole test |
| Throughput Controller and Throughput Timer | Chooses how often steps run | Paces threads to a request rate |
| Sample and transaction | One measured request | A group of requests as one business step |
Latency, Connect Time, and Response Time
Response time is the full time from sending a request until the whole answer has arrived. Connect time is the part spent opening the network connection. Latency is the time until the first byte of the answer arrives. If response time is large but latency is small, the server answered quickly but the body was big or the network was slow. If latency is large, the server itself or the path to it is slow to begin answering. Reading these three numbers together tells you where to look next.
Why These Pairs Matter
Each confusion above changes the load your server actually sees, and most of them change it quietly. The results still look like proper numbers, so nobody notices the mistake. A few minutes spent reading each setting carefully before you press start can save a day of chasing a false problem later.
Say out loud, in one sentence each, what your Thread Group will do about the number of users, the arrival pattern, the pauses, the repetition, and the end of the test. If you cannot say it clearly, the test is not ready.
30Frequently Asked Questions
Quick answers to the questions beginners ask most.
31Summary and Key Takeaways
The whole guide in a few lines.
Remember These Points
- A Thread Group controls the crowd: how many virtual users, how fast they arrive, and how long or how often they run.
- One thread equals one virtual user, and each thread owns its own copy of the test elements and variables.
- Ramp-up spaces thread starts evenly, so 100 threads over 50 seconds means about two new users every second.
- Choose thread counts from the business goal and Little’s Law, not from guesses, and always add realistic think time.
- Use several Thread Groups for different user types, and remember that every distributed worker runs the full group, which multiplies the load.
- Reach for setUp, tearDown, the Open Model group, or the Ultimate and Concurrency plug-ins when the standard group cannot shape the load you need.
- Run real tests in non-GUI mode, judge results by percentiles and errors, watch the load generator itself, and test only systems you are allowed to test.