A guide to JMeter thread group
September 11, 2024

A Guide to JMeter Thread Group

Performance Testing

The most important concept when it comes to creating a performance test using JMeter is the “virtual user.” This is the entity which represents a real user. In JMeter, it is known as “thread.” The JMeter Thread Group is a container which holds these virtual users and controls their behaviour — resulting in different workload models. 

JMeter Thread Group represents a logical group of business users. For example, if you have an online marketplace there will be a few specific groups of users to account for:

  • Buyers
  • Sellers
  • Administrators and/or moderators
  • Anonymous users arriving by search engine or accident

And each of these users should be represented by its own Thread Group.

In this blog, I will provide a thorough guide through what a JMeter Thread Group is, what it does, and how best to leverage them.

JMeter provides a wide range of thread group options for you to leverage based on your needs.

Back to top

JMeter Thread Group

The most commonly used JMeter groups is Thread Group. It is the most basic, yet powerful and flexible.

An example of JMeter thread group.

Action to be taken after a Sampler error

In the event of an unsuccessful Sampler (i.e. HTTP status code is above 399 or Assertion failed or it was a timeout), you can choose how to proceed. Your options are:

  • Continue - This is the default option and it means that if a request fails, the thread will simply proceed to the next request. Use it with caution because if the next request depends somehow on the previous one (correlation or part of a transaction) the next Samplers will cascade fail as well.
  • Start Next Thread Loop - You can specify the number of loops (iterations) via Loop Count parameter. If you choose this strategy, the thread will not proceed with the next Sampler execution if a failure occurs — it will start over from the very beginning.
  • Stop Thread - If a failure occurs, the current thread will be stopped. It will not execute anything else and the total number of active threads will be decreased.
  • Stop Test - If a failure occurs, JMeter will send a stop signal to all threads. This means it will trigger premature test termination.
  • Stop Test Now - Similar to Stop Test, but instead of “asking” users to finish execution of the current Sampler, JMeter will “tell” the threads to stop immediately and abort whatever operation is in progress. It will generate a number of errors related to abnormal connection terminations.

Number of threads (users)

As the name suggests, this identifies how many virtual users each Thread Group will be composed of.

Ramp-up period (seconds)

Ramp-up is the time to start all threads defined in the “Number of Threads” input. All threads will be started in the given time frame. The startup will be evenly distributed, so the load will increase gradually. Below are a few examples of JMeter ramp-up options:

  • 100 users, 100 seconds ramp-up time: means that JMeter will start 1 user per second
  • 100 users, 50 seconds ramp-up time: means that JMeter will start 2 users per second
  • 100 users, 200 seconds ramp-up time: means that JMeter will start 1 user every 2 seconds

It is important to increase the load gradually. This way you will be able to correlate increasing load with throughput, response time, number of errors, etc.

Loop Count

Loop count is how many times you want each virtual user to run Samplers defined in the Thread Group. 

JMeter acts as follows:

  • Once started, each virtual user starts executing Samplers upside down (or according to Logic Controllers).
  • When the last Sampler in the Thread Group is executed the virtual user starts a new iteration beginning from the first Sampler.
  • When there are no more Samplers to execute and Loops to iterate, the thread will shut down.
  • When the last thread is shut down, the test ends.

Make sure to provide enough loops to reach the desired concurrency. It is also possible to select the “Infinite” option or provide a negative number. This will instruct JMeter to run threads forever unless you stop the test on your own or the configured test duration is exceeded.

Same user on each iteration

This setting controls whether the user will be “new” or “returning” on the start of each loop (iteration). 

“Same user” means:

  • Connections will remain open.
  • Cookies will remain in the HTTP Cookie Manager.
  • Cache will remain in the HTTP Cache Manager.

If you choose “new” user, each iteration will start completely “from scratch” like in the very beginning of the test.

Delay Thread creation until needed

This setting controls the startup behaviour of the threads representing virtual users.

  • If the box is not ticked, JMeter will start all threads defined in “Number of Threads” when Thread Group starts. If your ramp-up period is long enough, there will be many idle threads waiting to start working.
  • If the box is ticked, JMeter will start threads “as needed” according to the scheduled ramp-up period.

In other words, do not tick the box if your ramp-up period is short. If your ramp-up period is long, it is better to tick the box.

Specify Thread Lifetime

Duration (seconds)

JMeter will not run the test longer than the specified duration. No matter how many Loops you have, the test will stop when test run time is exceeded. 

However, if you do not provide a sufficient number of Loops, the test will stop when the last thread finishes the last iteration — no matter what duration is specified.

Startup delay (seconds)

This field can be used for introducing a pause before starting the first thread. For example, if you started a background operation before the test (e.g. data generation or deployment of the system under test) and you know that it takes around 30 seconds, you can defer the startup of JMeter threads by that time.

Back to top

setUp Thread Group

One of the main features of the test is its repeatability. This means that when you re-run the same test you should get the same results. 

When the test is stateless (i.e. it does not modify anything) you should be able to re-run it as many times as you need without any problems. But if it modifies an entity, such as if you are testing an online marketplace with a limited quantity of products, when you check out the product the total number decreases. At some point, your checkout request will fail because no items are left in stock.

setUp Thread Group allows you to implement pre-conditions for the main test. For example, you can generate test users, test data, prepare the system under test for the main load. 

setUp Thread Group is executed before any other Thread Groups — no special configuration is required. If you have more than one setUp Thread Group, they will be executed in parallel.

All parameters are exactly the same as in the “normal” Thread Group.

Back to top

tearDown Thread Group

Again, this group deals with the matter of test repeatability. A well-behaved test must leave the system under test in its initial state. After completion of the “main” Thread Groups, you might want to perform a clean-up of any generated content, incomplete transactions, or entities generated during the test. 

tearDown Thread Group is executed after any other Thread Groups. No special configuration is required. Multiple tearDown Thread Groups are executed in parallel. 

All parameters are exactly the same as in the “normal” Thread Group

Back to top

Open Model Thread Group

The Open Model Thread Group is the most advanced of the Thread Groups bundled with JMeter.

Open Model Thread Group provides the possibility of configuring free-form load patterns that allow gradual ramp-ups and ramp-downs, spikes, plateaus, times of no action at all via pre-defined human-readable expressions. As of JMeter 5.6, the current supported patterns are:

rate(<number>/<unit of time>)

Specifies “arrivals” rate. This means you can set arrivals target, normally something like: 

rate(0/sec) random_arrivals(1 min) rate(10/sec)

It will ramp-up from 0 arrivals per second to 10 arrivals per second in 60 seconds.

If you add the following expression:

random_arrivals(1 min) rate(10/sec)

It will hold the load of 10 arrivals per second for another 1 minute.

And, finally, if you want to ramp-down to 0 arrivals per second back:

rate(10/sec) random_arrivals(1 min) rate(0/sec)

The interactive chart shows the workload model pattern:

Interactive workload model pattern.

JMeter Functions such as __groovy() can be used for generating the expressions. The expression can also be passed externally and read in the “Schedule” via __P() function.

Check out Rethinking Load Configuration With JMeter’s Open Model Thread Group for a more detailed explanation and examples.

Become a JMeter expert with BlazeMeter University's JMeter Pro course. Register today to master JMeter's elements, specialty plugins, popular protocols support, troubleshooting, and best practices.

REGISTER

Back to top

Custom Thread Groups

Before JMeter 5.5 where Open Model Thread Group was introduced, it was possible to create complex workload models using a “normal” Thread Group, ramp-up period and Timers. But it was not obvious what the load pattern for this would be.

The JMeter Plugins project adds missing functionality to JMeter such as new protocols, listeners, configuration elements, and several custom Thread Groups. 

All the plugins can be installed using JMeter Plugins Manager. The below Thread Groups are in the Custom Thread Groups bundle:

Custom thread groups bundle.Back to top

Stepping Thread Group

The Stepping Thread Group allows ramping up and down in equal, evenly distributed steps. It is also possible to configure a “plateau” phase so the load will be held for that time.

Ramping up and down in equal measure.

The interactive chart will update as you change any value and reflect the new load pattern.

Back to top

Ultimate Thread Group

The Ultimate Thread Group is extremely flexible in terms of defining ramp-up, ramp-down and time to hold the load for each line in the schedule. You can create multiple ramp-up, ramp-down, spikes, or plateaus.

Create multiple ramp-up, ramp-down, spikes, or plateaus.

There is also a special JMeter Property: threads_schedule which allows specifying the load pattern using the JMeter Properties approach.

The syntax is: 

spawn(threadsCount, initalDelay, startupTime, holdLoadFor, shutdownTime)

There can be multiple entries (whitespace separated). Each entry will represent a line in the Ultimate Thread Group schedules.

Back to top

Concurrency Thread Group

This thread group simply allows you to set the number of users, ramp-up period, number of ramp-up steps and time to hold the load.

Setting up multiple, concurrent tests.

But it has an effective feature when it comes to integration with the Throughput Shaping Timer plugin. 

Normally, JMeter Timers can only pause the threads in order to limit JMeter’s throughput to the given number of requests per unit of time. 

Concurrency Thread Group is capable of kicking off extra threads if the current amount is not sufficient to reach or maintain the desired throughput. Below is an example use case and the evidence from jmeter.log file:

Starting extra threads in JMeter.

At the bottom, you can see two more input fields where you can set:

Thread Iterations Limit

If you remember “normal” Thread Group, it was possible to set the number of iterations (loops) for the virtual user. By default, Concurrency Thread Group does not set any limits for the iteration so the virtual user will always be “returning.”

If you want a “new” user on each iteration, you must set the Threads Iterations Limit to 1.

Log Thread Status into File

This field can be used for debugging purposes. It generates a JTL results file in CSV format and responseMessage column can be either START or FINISH.

Back to top

Arrivals Thread Group

The Arrivals Thread Group manages “arrivals” instead of threads (virtual users) just like in Little's law.

The Arrivals Thread Group tries to reach and maintain the desired “arrivals” rate. It is capable of increasing the current number of virtual users if it is not sufficient.

Reaching and maintaining the desired "arrivals."

Concurrency Limit

This input field allows you to set the maximum number of threads (virtual users) the Arrivals Thread Group will be able to start. This provides some protection so the thread pools on the system under test won't be exhausted or the load generator runs out of resources or sockets. In that case, you will most likely not get the anticipated number of total arrivals. But you will be on the safe side when it comes to the maximum number of threads.

Back to top

Free-Form Arrivals Thread Group

The Free-Form Arrivals Thread Group feature is the similar to the Arrivals Thread Group. The difference is that it can have multiple “schedule” elements — allowing maximum flexibility when it comes to defining arrivals rate. With Arrivals Thread Group, you could only increase the arrivals rate in several steps. With the Free-Form Arrivals Thread Group, you can do whatever you want: create spikes, set the arrivals rate to zero, decrease the rate either suddenly or gradually, etc.

Creating a thread group with a variety of parameters.Back to top

Bottom Line

The JMeter Thread Group feature enables an efficient way to group your users during performance tests. It helps testers stay organized while also achieving the desired actions within any given test. As you can see, there are many ways in which you can leverage the JMeter Thread Group depending on your testing needs.

While testing with JMeter has its benefits, you can get even more out of them by pairing your JMeter tests with BlazeMeter. Doing so means you can easily scale all your performance tests while maintaining agility throughout.

Start getting the most out of your JMeter tests by testing with BlazeMeter for FREE today!

Start Testing Now

Back to top