Config Elements (General) in JMeter: The Complete Advanced Guide
Learn what Config Elements are, when and where they apply, how scope and execution order decide their effect, how each common element works, and how to design clean, safe and repeatable test plans with them.
Imagine you are opening a chain of coffee shops. Every shop needs the same sign, the same menu, the same uniform and the same payment machine settings. You would not ask each shop manager to invent these on the first morning. You would prepare a standard kit and hand it over, so that every shop starts the day with the right setup. In JMeter, the elements that prepare this standard kit for your requests are called Config Elements.
A JMeter test plan without Config Elements still works, but it becomes repetitive, fragile and hard to change. The server name is typed into fifty requests. The same header is added fifty times. A test data file is read in ways nobody remembers. With Config Elements, you set things once, in the right place, and every request inside that place inherits them. This guide explains the general ideas behind Config Elements first, and then goes through the common ones in depth, with the advanced details that experienced performance engineers care about.
1What Is a Config Element?
The elements that prepare the ground before requests are sent.
The simple definition
A Config Element is a JMeter test element that supplies settings, data or shared behaviour to the samplers that sit within its scope. It does not send a request by itself, and it does not produce a result of its own. Instead, it works quietly in the background: it fills in default values, adds headers, stores cookies, reads test data from a file, creates counters, or opens a connection pool. The samplers then use what the Config Element prepared.
The word “general” in the title of this guide points to the ideas shared by all Config Elements: where they live in the test plan, when they run, how their effect spreads down the tree, and how several of them combine. Once you understand these general rules, every specific element becomes easy to learn.
Think of a Config Element as the setup work in a kitchen before service begins. The cook chops vegetables, heats the oven and sets out the plates. None of this is a dish served to a customer, but without it no dish can be served correctly or quickly. Config Elements are the preparation that makes every sampler’s work simple.
What Config Elements do for you
They reduce repetition, because shared values live in one place. They make the test plan easier to maintain, because a change in one place updates every request. They make the test more realistic, because they can simulate browser behaviour such as cookies and caching. They feed the test with data, such as different user names for each virtual user. And they make test plans portable between environments, because the server address can be changed in one element instead of fifty samplers.
Whenever you notice yourself typing the same value into a second sampler, stop and ask whether a Config Element could hold it instead. This habit alone makes test plans much shorter and much safer to change.
2Config Elements Among the Other JMeter Elements
Knowing the neighbours helps you pick the right tool for each job.
A JMeter test plan is built from several families of elements, and each family has a clear role. Beginners often use the wrong family for a task, such as using a script to add a header that a Config Element could add without any code. The table below shows the roles side by side.
Config Elements
Prepare settings, data and shared behaviour for the samplers in their scope.
Samplers
Do the real work: send a request, run a query, call a service. Each run creates a result.
Pre-Processors and Post-Processors
Change things just before a sampler runs, or read and capture values just after it finishes.
Timers
Add pauses and control the pace of requests.
Assertions
Check the result and decide whether the sample passed or failed.
Listeners
Show, summarise or save the results.
| If you want to… | Use | Reason |
|---|---|---|
| Set the server name once for many requests | Config Element (HTTP Request Defaults) | Shared setting, no code needed |
| Add the same header to every request | Config Element (HTTP Header Manager) | Applied automatically in scope |
| Read a different user name for each virtual user | Config Element (CSV Data Set Config) | Built-in data feeding |
| Capture a token from a response | Post-Processor (extractor) | Reads a specific response |
| Wait between two steps | Timer | Controls pace |
| Check that a page contains a word | Assertion | Judges the result |
The key difference from processors
Config Elements prepare conditions that are true for many samplers, while processors act on one particular sampler’s run. A Config Element is like a rule on the wall of a room, while a processor is like a person who acts when a certain event happens. Config Elements are usually set once and left alone, while processors usually react to the specific response in front of them.
Using a script-based pre-processor to set a header or a host name because it “feels flexible”. Scripts cost CPU time under high thread counts and are harder to read. If a Config Element can do the job, use it. Keep scripts for logic that no built-in element offers.
3Execution Order: When Config Elements Run
Timing decides what a sampler can see, so the order must be clear.
JMeter processes elements in a fixed order for every sampler run. Config Elements come first, before pre-processors, timers, the sampler itself, post-processors, assertions and listeners. This is logical: the sampler can only use settings that have already been prepared.
flowchart TD
A["Config Elements apply settings and data"] --> B["Pre-Processors modify the request"]
B --> C["Timers add pauses"]
C --> D["Sampler sends the request"]
D --> E["Post-Processors read the response"]
E --> F["Assertions check the result"]
F --> G["Listeners show and save the result"]
The special case of User Defined Variables
There is one important exception. The Config Element called User Defined Variables is processed once, at the very start of the test, in the order it appears in the test plan, and it does not matter where it is placed. So a variable defined there is available everywhere from the beginning, but it cannot refer to a variable defined further down, because that one has not been processed yet. This behaviour surprises many people, and it explains many “variable not found” problems.
Test starts
All User Defined Variables are processed in the order they appear, and their values become available to all threads.
Thread begins an iteration
For each sampler the thread is about to run, the Config Elements in scope apply their settings first.
Data elements deliver values
Elements such as the CSV Data Set Config and the Counter place the next value into thread variables.
The sampler runs
It uses the defaults, headers, cookies, variables and connections that the Config Elements prepared.
Imagine a school morning. The principal’s announcements about the day are made once at assembly, before any class begins, and they apply to everyone. That is how User Defined Variables behave. Each teacher’s own classroom rules are applied at the start of that teacher’s lesson. That is how most other Config Elements behave.
Because User Defined Variables run at the start for every thread alike, they are meant for constants such as a server name, a base path or a wait time. Do not use them for values that must differ per user. Use a data file or a counter for that.
4Scope and Inheritance: Where a Config Element Takes Effect
A Config Element affects only the part of the test plan tree where it sits.
The test plan is a tree. A Config Element influences the samplers that are its siblings and the samplers inside its sibling controllers. Samplers outside that part of the tree do not see it. This simple rule is called scope, and it is the most important general idea about Config Elements.
flowchart TD
TP["Test Plan"] --> TG["Thread Group: Shoppers"]
TG --> CE1["Config: HTTP Request Defaults"]
TG --> CE2["Config: HTTP Header Manager"]
TG --> S1["Sampler: Open home page"]
TG --> TC["Transaction: Checkout"]
TC --> CE3["Config: extra header for payment"]
TC --> S2["Sampler: Submit payment"]
TG --> TG2["Thread Group: Admins"]
TG2 --> S3["Sampler: Open admin page"]
The nearest one wins
When several Config Elements of the same kind are in scope for a sampler, JMeter combines them. For values that clash, the one closest to the sampler generally takes priority over the one placed higher in the tree. Values typed directly inside a sampler win over defaults. This lets you set broad rules high in the tree and exceptions deep in the tree, just as a company has general policies and a department may have a special rule.
| Place in the tree | Reaches | Typical use |
|---|---|---|
| Test Plan level | All thread groups below | Environment constants and global defaults |
| Thread Group level | All samplers in that group | Defaults, headers and cookies of that user type |
| Inside a controller | Only samplers in that controller | Exceptions for one business step |
| Next to one sampler | Only that sampler | A single special case |
Placing a Config Element in one thread group and wondering why samplers in another group ignore it. Elements do not travel sideways. If two groups need the same setting, place it higher, at the test plan level, or repeat it in both groups on purpose.
5The Catalogue of Common Config Elements
A map of the elements you will meet most often.
JMeter ships with many Config Elements, and the plugin collection adds more. The table below lists the ones most teams use, grouped by purpose. The following chapters explain the important ones in depth.
| Purpose | Element | What it does |
|---|---|---|
| Constants | User Defined Variables | Holds named values that are available to the whole test |
| Defaults | HTTP Request Defaults | Supplies server, port, protocol, path and other fields to web samplers |
| Defaults | FTP, LDAP, TCP and Java Request Defaults | Supply default settings to samplers of those types |
| Web behaviour | HTTP Header Manager | Adds headers to requests |
| Web behaviour | HTTP Cookie Manager | Stores and sends cookies for each virtual user |
| Web behaviour | HTTP Cache Manager | Simulates a browser cache |
| Web behaviour | DNS Cache Manager | Controls how host names are resolved |
| Security | HTTP Authorization Manager | Supplies credentials for basic and other authentication types |
| Security | Keystore Configuration | Loads client certificates for secure connections |
| Security | Login Config Element | Supplies a user name and password to samplers that need them |
| Data | CSV Data Set Config | Reads rows from a file into variables |
| Data | Counter | Produces increasing numbers |
| Data | Random Variable | Produces random numbers in a range |
| Connections | JDBC Connection Configuration | Creates a named database connection pool |
| Generic | Simple Config Element | Holds name and value pairs for elements that read them |
Constants and defaults
Remove repetition. Set values once and let every sampler inherit them.
Browser behaviour
Headers, cookies, cache and name resolution make virtual users behave like real browsers.
Security
Credentials and certificates for protected services.
Data and connections
Feed each user unique data and manage database connection pools.
A good starter set for almost any web test is: User Defined Variables for constants, HTTP Request Defaults for the server, an HTTP Header Manager for common headers, an HTTP Cookie Manager for sessions, and a CSV Data Set Config for user data. Add the others when the scenario needs them.
6User Defined Variables and Properties
The place for constants, and the difference between a variable and a property.
What User Defined Variables hold
The User Defined Variables element is a simple table of names and values. Once defined, a value can be used anywhere in the test plan by writing its name inside the variable placeholder syntax. Typical contents are the server name, the base path, the protocol, a standard wait time, a product category used by many requests, or an environment label. Changing one row changes every place that uses it.
Variables versus properties
JMeter has two kinds of named values, and confusing them causes many problems. A variable belongs to a thread. Each virtual user has its own set of variables, and extractors and data files fill them while the test runs. A property belongs to the whole JMeter process. It is shared by all threads and can be set from the command line when you start the test, which makes properties ideal for values that change between runs, such as the number of threads, the duration or the target environment.
| Aspect | Variable | Property |
|---|---|---|
| Belongs to | One thread | The whole JMeter process |
| Filled by | User Defined Variables, extractors, data files, counters | Properties files and command-line options |
| Can differ per user | Yes | No |
| Best for | User data, tokens, captured values | Run settings and environment choices |
| Shared between workers | No, each machine has its own | Each machine needs the same setting passed |
Combining both: a flexible pattern
A powerful pattern is to put a property function inside a User Defined Variables row, with a default value. The variable then uses the value passed on the command line if there is one, and falls back to the default otherwise. This lets the same test plan run on a laptop with small numbers and in the pipeline with large numbers, without any edits to the plan file. It also keeps secrets and environment details out of the plan itself.
A property is like the thermostat setting for the whole building, set by the manager before opening. A variable is like each person’s own notepad on their desk. Everyone follows the building temperature, but everyone writes different notes.
Using a User Defined Variables row for per-user data, expecting each thread to get a different value. All threads see the same value there. If you need different values per user, use a data file, a counter or a random variable.
Example: one plan, three environments
A team keeps one test plan. The server name, the number of threads and the duration are read from properties with safe defaults. For a quick check they run the plan with defaults. For the nightly pipeline they pass the staging server and a bigger load. For a pre-release rehearsal they pass the production-like server. The plan file never changes between these runs.
Put all your User Defined Variables in one clearly named element near the top of the plan, and give variables descriptive names such as server host and base path. Anyone opening the plan then finds all constants in one place.
7HTTP Request Defaults
Set the server once and let every web request inherit it.
The HTTP Request Defaults element provides default values for HTTP samplers in its scope. Any field that you leave empty in a sampler is filled from the defaults. A sampler that has its own value keeps it. This is the simplest and most useful way to remove repetition from a web test plan.
Protocol, server and port
The basic address of the application. Setting them here means individual requests only need the path.
Path and content encoding
A common starting path and the character set used for sent data, which avoids garbled characters in non-English text.
Timeouts
Connect and response timeouts. Without them, a stalled server can hold threads for a very long time and hide how many users really waited.
Embedded resources
Whether to download images, styles and scripts after a page, using a pool of parallel downloads, and an optional pattern that limits which addresses are fetched.
Parameters
Query or form values that should be sent with every request in scope.
Implementation and proxy
The underlying web client to use and any proxy settings that all requests should follow.
Benefits in daily work
With defaults in place, moving a test from one environment to another means editing one element, or better still, one variable that the element reads. Timeouts are applied consistently, so that no request waits forever. Embedded resource rules are applied in one place, so that all pages behave the same way. And the sampler list becomes short and readable, with only the path and the parameters that make each request different.
Several hosts in one plan
Some applications call more than one host, such as the main site, an image service and a payment service. Use one defaults element for the main host at the thread group level, and override the server in the samplers that call other hosts. Alternatively, place the samplers for each host under separate controllers, each with its own defaults element. The nearest element wins, so each branch uses its own host.
flowchart LR
D["HTTP Request Defaults: server, port, timeouts"] --> S1["Sampler with empty server field: uses defaults"]
D --> S2["Sampler with empty server field: uses defaults"]
O["Sampler with its own server value"] --> R["Keeps its own value, ignores the default"]
Leaving a leftover server name inside an old sampler after introducing defaults. The sampler quietly ignores the defaults and keeps calling the old host, and the test hits the wrong environment. After adding defaults, clear the server field from every sampler and confirm in the request details.
Set sensible connect and response timeouts here. A test with no timeouts can hide a saturation problem, because stalled threads simply wait and the report shows fewer, slower requests instead of clear timeout errors.
8HTTP Header Manager
Headers tell the server how to treat each request, and they are easy to get wrong.
The HTTP Header Manager holds a table of header names and values. Every HTTP request in its scope is sent with these headers. Headers describe the kind of content being sent, the kinds of content the client accepts, the client’s identity, and credentials such as access tokens.
| Header | Purpose | Typical use in tests |
|---|---|---|
| Content type | Says what kind of data is in the request body | Required for sending structured data to services |
| Accept | Says what response formats the client understands | Selects between formats offered by a service |
| Authorization | Carries credentials or an access token | Secured service calls, often filled from a variable |
| User agent | Identifies the client software | Mimic a real browser or a mobile device |
| Accept encoding | Allows compressed responses | Matches real browser behaviour and reduces transfer size |
| Custom headers | Application-specific values | Correlation identifiers, feature flags, tenant names |
How several managers combine
You may place more than one Header Manager in a test plan, for example a general one at the thread group level and a special one for a single step. JMeter merges the headers from all managers in scope. If the same header name appears in two of them, the one nearer the sampler wins. This allows a common set at the top and small overrides below, which keeps the plan short and the exceptions easy to spot.
Headers with dynamic values
Header values can use variables. A typical case is an authorisation header whose value contains an access token captured from a login response. The extractor stores the token in a thread variable, and the header manager places it into every following request. Because variables belong to threads, each virtual user sends its own token, exactly as real users would.
Headers are like the label stuck on a parcel: sender, content type, handling instructions, and a pass for the building security. A parcel with a missing or wrong label may still travel, but the receiver may refuse it or treat it wrongly.
Forgetting the content type header when sending structured data. The server may then reply with a client error or silently misread the body. When a service call fails with a code in the four hundreds, check the headers in the request details before anything else.
Example: tracing a request across systems
A team adds a custom correlation header to every request through one Header Manager, with a value that combines the thread name and a counter. Server logs now show the same identifier, and engineers can follow one virtual user’s slow request through the web server, the application and the database.
Copy the real headers from a browser’s developer tools for one working request, and reproduce the important ones in the manager. Tests with browser-like headers behave much more like production, including compression and caching decisions made by the server.
9HTTP Cookie Manager
Cookies keep sessions alive, and every virtual user needs its own jar.
Web applications use cookies to remember who you are between requests. After you log in, the server sends a session cookie, and your browser sends it back with every later request. Without cookie handling, JMeter would look like a stranger on every request, and any page that needs a login would fail. The HTTP Cookie Manager stores cookies received from the server and sends them back, just as a browser does.
One jar for each virtual user
The cookies stored by the manager belong to each thread separately. This is exactly what you want: every virtual user has its own login session and its own cookie jar. It also means that one thread’s session never leaks into another’s, which keeps users independent.
Clear cookies each iteration
When on, each loop of the scenario starts with an empty jar, so the thread acts like a new visitor. When off, the thread keeps its session across loops like a returning visitor.
Cookie policy
Decides how strictly cookie rules are applied. The default suits most modern sites, but older or unusual servers may need a different policy.
User-defined cookies
A table where you can add cookies yourself, such as a consent cookie or a language setting, so the application skips a pop-up or a first-visit page.
Why “clear cookies each iteration” matters
This single option changes the meaning of your test. If your scenario starts with a login and you leave cookies from the previous loop in place, the second loop may skip a real login on the server side, giving unrealistic speed. If you clear them, each loop makes a full login, which is closer to many different users arriving. Decide which behaviour matches your business question, and write it in the test notes.
Placing more than one Cookie Manager in the same thread group. This can cause unpredictable behaviour and confusing session problems. Use one manager per thread group, placed at the group level.
A cookie is like a wristband given at the entrance of a festival. Show it at each stall and you are recognised without paying again. A cookie manager is the wallet that remembers your wristband. Giving every visitor their own wallet keeps everyone’s passes separate.
Example: login works once, then fails
A tester found that every virtual user could log in on the first loop, but the second loop failed. The scenario started with the login page, but the cookie from the first loop was still present, so the server treated the new login as a repeated one and refused it. Turning on the option to clear cookies each iteration fixed the problem at once.
10HTTP Cache Manager
Real browsers do not download everything every time, and your test should not either, unless you want it to.
Real browsers keep a copy of static files such as images, scripts and style sheets, and reuse them on later visits. A JMeter thread without a cache downloads every file every time. This can make your test far heavier than reality: more bytes, more requests and more load on content delivery. The HTTP Cache Manager adds browser-like caching to each virtual user.
How it works
The manager remembers resources a thread has already downloaded, together with their freshness information. On the next request for the same resource, it can skip the download if the resource is still fresh, or send a conditional request asking the server whether it changed. Resources served from the simulated cache cost almost no time, and they are marked in the results in a special way. The cache is kept for each thread separately.
Clear cache each iteration
When on, each loop is a first-time visit with an empty cache. When off, later loops behave like repeat visits.
Use cache control and expiry headers
Makes the manager follow the freshness rules sent by the server, as a real browser does.
Maximum cache size
Limits the number of items kept per thread, protecting memory when many threads each hold many resources.
Choosing between first-visit and repeat-visit tests
The right setting depends on your audience. A news site with many returning readers should test mostly with caching on. A flash sale where most visitors arrive for the first time should test with caching off, or with the cache cleared every loop. Many teams run both and compare them: the first-visit run shows the worst case for the network and the content layer, and the repeat-visit run shows the typical case.
| Scenario | Cache setting | Why |
|---|---|---|
| Flash sale with mostly new visitors | Clear cache each iteration | Every user downloads everything once |
| Daily-use business application | Cache kept between loops | Users see static files already stored |
| Worst-case capacity test | Cache off or cleared | Maximum load on servers and network |
| Realistic mixed audience | Mix of both in separate groups | Matches the share of new and returning users |
Comparing a test that used the cache manager with one that did not, and concluding that the application got faster or slower. The difference may come only from fewer downloads. Keep the cache settings identical between tests you want to compare.
If you do not retrieve embedded resources in your test at all, a cache manager has little to do. It matters most when pages download many static files, so enable both settings together and keep them consistent.
11Security Config Elements: Authorization, Keystore and Login
Giving virtual users the credentials and certificates they need.
HTTP Authorization Manager
Holds a list of addresses with a user name, a password and an authentication method such as basic, digest, Kerberos or a Windows-based scheme. Requests to matching addresses are sent with the right credentials.
Keystore Configuration
Loads a client certificate store for services that require mutual secure connections, where the client must also prove its identity with a certificate.
Login Config Element
Supplies a simple user name and password pair to samplers that read them, such as some mail or file transfer samplers.
How the Authorization Manager chooses what to send
The manager compares the address of each request with the base addresses in its table. If the request matches, the credentials in that row are used. This means you can set different credentials for different parts of an application, and requests to unrelated addresses are left alone. The credentials in this table are shared by all threads, so it suits cases where all virtual users may use the same service account, or where each thread should receive credentials through a variable.
Client certificates
Some corporate and financial services demand that clients present a certificate. The Keystore Configuration element loads the certificate store and chooses which certificate entries to use. It can also expose the chosen entry through a variable, which helps when different virtual users must use different certificates. Because certificate loading and secure handshakes are CPU-heavy, a test with many certificates and many threads can load the generator much more than a test without them, so size the machines accordingly.
Credentials typed into these elements are stored in the test plan file in readable or only lightly protected form. Anyone who gets the file gets the credentials. Use dedicated test accounts, never real personal or production administrator accounts, and keep plan files in protected storage.
For services that use token-based security, the Authorization Manager is often not needed. A header manager that sends a captured token is usually simpler and closer to how modern applications work. Choose the element that matches the way your application really authenticates.
These elements are like the identity badges and key cards given to staff at the start of a shift. Some doors need a password, some need a badge, and some need a special key card. Giving each worker the right pass before the shift prevents queues at the door.
12CSV Data Set Config: Feeding Each User Different Data
The most important data element, and the one with the most settings to get right.
If every virtual user logs in with the same account and searches for the same word, your test is unrealistic. Caches answer instantly, accounts get locked, and databases see the same row again and again. The CSV Data Set Config reads rows from a text file and places the values of each row into variables. Each time a thread starts a loop, it receives the next row.
File name and encoding
Where the file is, and how to read its characters. Relative paths are resolved from the folder of the test plan, which matters when the plan moves between machines.
Variable names and delimiter
Names for each column, and the character that separates columns. Alternatively, the first line of the file can supply the names.
Ignore first line
Skips a header row so that column titles are not used as data.
Allow quoted data
Lets values contain the delimiter inside quotation marks, such as an address with a comma.
Recycle on end of file
Decides whether to start again from the first row when the file ends.
Stop thread on end of file
Decides whether a thread should end when no more rows are left, instead of continuing with empty values.
Sharing mode
Decides who shares the file pointer: all threads, one thread group, or each thread separately.
Sharing modes explained
| Sharing mode | What happens | Typical use |
|---|---|---|
| All threads | One file pointer for the whole test. Every thread takes the next free row, so rows are not repeated until recycled. | Unique accounts for every user and every loop |
| Current thread group | Each thread group has its own pointer over the same file. | Different user types reading their own data |
| Current thread | Each thread reads the whole file from the top on its own. | Every user performs the same list of actions in order |
| Named identifier | Elements with the same identifier share a pointer. | Several data elements that must move together |
flowchart TD
F["Data file with rows"] --> M{"Sharing mode"}
M -->|"All threads"| A["One shared pointer: each thread takes the next unused row"]
M -->|"Current thread"| B["Each thread reads the whole file separately"]
A --> E{"End of file reached?"}
E -->|"Recycle on"| R["Start again from the first row"]
E -->|"Stop thread on"| S["Thread ends"]
E -->|"Both off"| X["Threads receive empty or repeated values and tests fail"]
Planning the amount of data
Before running, calculate the number of rows you need. With the shared mode, the rows used equal the number of threads multiplied by the number of loops each thread runs. A file of 500 rows is enough for 500 threads doing one loop, but not for 500 threads running for an hour with a loop every two minutes, which needs around 15,000 rows. Include a margin, and decide in advance what should happen at the end of the file.
Leaving both recycle and stop thread switched in a way that lets threads run past the end of the file. Threads then keep using the last value or an empty value, and the application sees a flood of identical or invalid requests. Always decide what should happen at the end of the data.
Keep data files small and clean: no blank lines at the end, no hidden characters, and a consistent delimiter. A single bad line can produce a confusing failure for one unlucky thread, which is hard to spot among thousands of samples.
13Counter and Random Variable
When you need numbers that grow or vary, without preparing a data file.
The Counter
The Counter element produces a number that increases each time it is used. You set the start value, the step, an optional maximum, and a format, such as adding leading zeros. The number is stored in a variable that other elements can read. It is very useful for unique values: order references, email addresses, file names or search terms that must not repeat.
Track counter independently for each user
When on, each thread has its own counter that starts again at the start value. When off, all threads share one counter and receive different numbers.
Reset on each thread group iteration
Restarts the counter at the beginning of each loop. Useful when a loop needs the same series of numbers every time.
Format and exported variable
Number format for readable codes, and an optional second variable that holds the current value for use elsewhere.
The Random Variable
The Random Variable element generates a random number between a minimum and a maximum and stores it in a variable. It is useful for picking a random product number, a random page number or a random delay. You can choose a format and a seed. Using the same seed produces the same series of random numbers on each run, which makes tests repeatable. Choosing whether the random series is shared by all threads or separate for each user changes how varied the traffic looks.
| Need | Best element | Reason |
|---|---|---|
| Unique order reference for every request | Counter shared by all threads | Numbers never repeat |
| Each user numbers their own items from one | Counter per user | Every thread starts at the same value on its own |
| Random product from a catalogue of known size | Random Variable | Quick spread across the range |
| Specific real values such as real product codes | CSV Data Set Config | Random numbers might not match real records |
Using a random number for a value that must exist in the database, such as a product identifier, when the identifiers have gaps. Many requests then ask for items that do not exist, and the application returns errors or empty pages, which are fast and cheap, producing flattering but meaningless results. Use real data for real identifiers.
A counter is like the ticket machine at a bank, handing out numbers one after another. A random variable is like pulling a number out of a hat. A data file is like a printed guest list: every name is real and exactly as written.
In a test with several worker machines, each machine has its own counter that starts from the same value. Two workers can therefore produce the same number at the same time. Give each worker a different start value, or include the machine name in the generated value, to keep it unique.
14JDBC Connection Configuration
A shared pool of database connections that samplers borrow by name.
To test a database directly, JMeter needs connections. The JDBC Connection Configuration element creates a named pool of database connections. A database sampler then refers to the pool by its name. All threads share the pool, so its size matters a great deal.
Variable name of the pool
The name that database samplers use to find this pool. It must match exactly.
Maximum number of connections
The most connections the pool will open. If it is smaller than the thread count, threads wait inside JMeter for a free connection.
Pool timeout and idle cleanup
How long a thread may wait for a connection and how often unused connections are closed.
Validation query and auto commit
A tiny query that checks a connection is alive, and the choice of committing every statement automatically or not.
Address, driver and credentials
The database address, the driver class, and the user name and password. The driver library must be present on every JMeter machine.
The pool size decides what you measure
If the pool is smaller than the number of threads, many threads must wait for a free connection. That waiting time happens in JMeter, but depending on how the sampler measures, it may be included in the response time you report. The database then looks slower than it is. If the pool is much larger than a real application would use, you may overload the database with a number of connections that production would never open. The sensible choice is to mirror the connection limit of the real application, or to deliberately test beyond it when exploring capacity.
flowchart LR
T1["Thread 1"] --> P["JDBC pool: limited number of connections"]
T2["Thread 2"] --> P
T3["Thread 3"] --> P
T4["Thread N"] --> P
P --> D["Database"]
Forgetting to put the database driver library on the load generators, especially on worker machines in a distributed test. The pool then fails to start, and every database sample fails with a driver error that looks like a database problem.
Example: a pool that hid the real capacity
A team tested a reporting query with 200 threads and a pool limited to 20 connections. Response times looked terrible and the database looked overloaded, but the database’s own monitoring showed low load. The pool was making threads queue. Raising the pool to match the application’s real limit gave a true picture and a very different conclusion.
15DNS Cache Manager, Protocol Defaults and the Simple Config Element
The quieter members of the family, each useful in the right situation.
DNS Cache Manager
Before JMeter can connect to a host name, the name must be turned into a network address. By default the Java runtime caches the answer for a while, so every thread keeps using one address. This can send all your load to a single machine behind a name that has many addresses. The DNS Cache Manager lets you control this: clear the cache each iteration, use the system resolver or a custom one, and even define your own host entries that map names to chosen addresses. This is valuable when testing a load-balanced site where you want to spread requests, or test one specific server, or point a production name at a test environment.
If one server behind a load balancer is busy and the others are idle during your test, suspect name resolution caching. All threads may be connected to the same address. The DNS Cache Manager is the element that helps spread them.
Protocol-specific defaults
The idea behind HTTP Request Defaults repeats for other protocols. There are defaults elements for FTP requests, LDAP directory requests, raw TCP samplers and Java-based request samplers. Each one holds the settings that the matching samplers share, such as the server, the port, timeouts and common options. The same rules of scope and nearest-wins apply.
| Element | Used with | Typical fields |
|---|---|---|
| FTP Request Defaults | FTP samplers | Server, port, user and password settings |
| LDAP Request Defaults | Directory samplers | Server, port, base search path |
| TCP Sampler Config | Raw network samplers | Server, port, timeouts, end-of-message handling |
| Java Request Defaults | Java-based samplers | Class name and parameter list |
Simple Config Element
The Simple Config Element is a flexible holder for name and value pairs. By itself it does nothing. Other elements, especially those from plugins, read from it to find their settings. If a plugin’s documentation asks you to add a simple config element with certain names, this is the element it means.
Plugin Config Elements
The plugin collection adds more data elements. A popular one reads rows from a file in random order or lets rows be used only once. Others read from remote data stores. These are useful when the standard CSV element is not enough, but they bring extra software to every machine, so record plugin versions and install them identically on all generators.
Installing a plugin only on the machine where the plan was written and then running the plan on other machines. The elements appear as unknown or broken, and the test fails to start or behaves differently. Keep every machine on the same JMeter version and plugin set.
These elements are the less famous staff in a theatre: the person who sets the stage lights, the one who keeps the prompt book, and the one who knows where every prop belongs. The audience never sees them, but the show falls apart without them.
16Config Elements, Thread Counts and the Cost of Realism
Every realistic setting has a price in memory, processor time and planning.
Config Elements make a test more realistic, but realism is never free. When hundreds of threads each hold their own cookie jar, their own cache and their own variables, the memory of the load generator is the first to feel it. Understanding where the costs sit helps you size your machines and plan your data.
Cookie Manager
Small memory per thread. Almost always worth its cost, because sessions are essential.
Cache Manager
Holds copies of resource information per thread. With large pages and many threads, the memory adds up, so limit the cache size.
CSV Data Set Config
Reads rows as needed. Cost is low, but the shared file pointer is a tiny point of contention at very high rates.
Keystore and secure handshakes
CPU-heavy. Client certificates make every new connection more expensive for the generator.
JDBC pool
Each connection uses memory on the generator and on the database server. Match it to real use.
Embedded resource download
A defaults setting that multiplies requests per page. It increases load, bytes and the number of results saved.
Plan your data from the thread count
Data needs grow with threads and time. Use a simple method: rows needed equal the number of threads multiplied by the number of loops each thread will complete. For time-based tests, loops equal the test duration divided by the cycle time of one loop. Then add a margin of twenty percent or more. Prepare the data before the test day, check that every account can log in, and check that none is locked or expired.
| Threads | Test length | Cycle per loop | Rows needed |
|---|---|---|---|
| 100 | 30 minutes | 3 minutes | About 1,000 with margin |
| 500 | 1 hour | 5 minutes | About 7,200 with margin |
| 1,000 | 2 hours | 2 minutes | About 72,000 with margin |
Running a long test with a data file sized for one loop per user. When the data runs out, the settings at the end of the file decide what happens, and many teams discover too late that half of the test ran with empty values.
When memory is tight, remove realism you do not need. A back-end service test rarely needs a browser cache or embedded resource downloads. Keep only the Config Elements that the business question requires.
17Config Elements in Distributed Tests
What changes when one plan runs on many machines.
In a distributed test, the controller sends the plan to each worker, and every worker runs it independently. Config Elements are part of the plan, so each worker runs its own copy of each element. This has several important consequences.
flowchart TD
C["Controller: sends the plan to each worker"] --> W1["Worker 1: own copy of every Config Element"]
C --> W2["Worker 2: own copy of every Config Element"]
C --> W3["Worker 3: own copy of every Config Element"]
W1 --> A["Own data pointer, own counter, own pool"]
W2 --> B["Own data pointer, own counter, own pool"]
W3 --> D["Own data pointer, own counter, own pool"]
Data files must exist on every worker
The CSV element reads from the worker’s own file system. If a file is missing on a worker, that worker’s threads fail at once.
Workers read the same rows unless you split the data
Each worker has its own file pointer. If all workers hold the same file, they all start at row one, and different workers use the same accounts at the same moment. Give each worker its own slice of the data.
Counters start together
Each worker’s counter starts at the same value, so numbers collide across machines. Use different start values or add a worker identifier.
Pools multiply
A database pool of 20 connections on each of five workers means up to 100 connections on the database server. Size accordingly.
Properties must be passed to each worker
A property set on the controller does not automatically apply to workers. Pass the same settings to every machine, or use a method that sends them along.
Typing the total number of users into a thread group and running it on several workers. Every worker then runs the full number, and the real load is a multiple of the plan. Divide the target by the number of workers.
Example: duplicate orders from colliding counters
A team ran a test on four workers, each creating order references from a counter that started at one. The application rejected many orders as duplicates. The team gave each worker its own start value, in separate ranges, and the duplicates disappeared.
18Design Patterns for Layered and Portable Configuration
Habits that keep large test plans tidy, safe and easy to change.
Pattern 1: layer your configuration
Arrange Config Elements in layers, like the rules of a company. At the top, at test plan level, place constants and settings that apply everywhere. At the thread group level, place the defaults, headers, cookies and data of that type of user. Inside controllers, place small exceptions for one business step. At the sampler level, type only what is unique to that request. A reader who opens the plan can then find any setting by asking “which layer owns this?”.
flowchart TD
L1["Layer 1: Test Plan constants and run settings"] --> L2["Layer 2: Thread Group defaults, headers, cookies and data"]
L2 --> L3["Layer 3: Controller level exceptions"]
L3 --> L4["Layer 4: Sampler specific values"]
Pattern 2: make the plan environment-neutral
Never hard-code a server name, a user count or a duration into a sampler. Keep them in User Defined Variables that read properties with safe defaults. One plan can then serve a laptop check, a nightly run and a full rehearsal, simply by passing different properties at start time.
Pattern 3: one purpose per element
Give each Config Element a clear name that states its purpose, such as “Shopper headers” or “Test accounts data”. Avoid one large element that tries to do everything. Clear names turn the tree into documentation.
Pattern 4: keep secrets outside the plan
Read passwords and keys from files or properties that are kept in protected storage, rather than typing them into elements. Then the plan can be shared and stored in version control without exposing secrets.
Pattern 5: separate user types
When user types behave differently, use separate thread groups, each with its own cookie manager, header manager and data element. This keeps their sessions, headers and data apart, and each group can be scaled on its own.
| Pattern | Benefit | Risk when ignored |
|---|---|---|
| Layered configuration | Settings are easy to find and change | Duplicate and conflicting settings spread across samplers |
| Environment-neutral plan | Same plan for every run | Plans copied and edited per environment, drifting apart |
| Clear element names | The tree explains itself | New team members cannot read the plan |
| Secrets outside the plan | Safe sharing and storage | Credentials leak with the file |
| Separate user types | Independent sessions and data | Mixed cookies, headers and data between groups |
Store the plan in version control with a short readme that lists the properties it expects and their defaults. A new teammate can then run the plan correctly on the first day without asking anyone.
19Security and Privacy of Configuration
Configuration is where secrets like to hide.
Config Elements often contain the most sensitive details of a test: server addresses, user names, passwords, tokens, certificates and database credentials. A test plan file is therefore a sensitive document. It is often emailed, stored in shared folders and committed to code repositories, and each of these steps can expose its secrets.
Credentials in the plan
Passwords in authorisation elements, login elements and database configuration sit in the plan file.
Real accounts in data files
Data files with real customer details, or real staff accounts, may leak private data and cause real side effects.
Tokens in headers
A header manager with a fixed access token gives access to anyone who can read the plan.
Certificates and keys
Client certificate stores and their passwords allow impersonation of the test client.
Protective habits
Use synthetic accounts and data
Create dedicated test users with limited rights. Never load-test with real customer records.
Pass secrets at run time
Supply passwords and keys through protected properties or files at start time, not by typing them into elements.
Protect plan and data files
Store them in access-controlled places and keep secrets out of version control history.
Rotate test credentials
Change test passwords and tokens after sharing a plan or after large tests, so that anything that leaked becomes useless.
Treat a test plan like a configuration file for the application itself. If it would be a problem for an outsider to read it, then store it and share it with the same care as any secret.
20Debugging Config Elements
How to see what a Config Element is really doing.
Config Elements work silently, which makes them hard to debug. A header is missing, a cookie is not sent, a variable is empty, or a request goes to the wrong server, and nothing in the plan screams. The way to debug is to look at the evidence: what the sampler really sent and what values the thread really held.
Run with one thread
Debug with a single thread and one loop. Problems that appear here are plan problems, not capacity problems.
Open the request details
In the results tree, read the request tab. Check the address, the headers, the cookies and the body. Every effect of defaults, header managers and cookie managers shows here.
Use the debug sampler
Place a debug sampler where you want to see the current variables and properties. Its result lists what the thread holds at that moment, including values from data files and counters.
Check scope and order
If an element seems to have no effect, confirm that it sits in the right branch and that nothing nearer the sampler overrides it.
Read the log
The JMeter log file reports problems such as missing data files, unknown variables and driver errors, often with the name of the element concerned.
| What you suspect | Where to look |
|---|---|
| Header missing or wrong | Request tab: header lines of the sampler |
| Cookie not sent | Request tab: cookie line, and the previous response’s set-cookie header |
| Wrong server or port | Request tab: the address, and sampler fields that may override defaults |
| Variable empty | Debug sampler output and the data element’s file settings |
| Data repeating | Sharing mode and recycle settings of the data element |
| Database sample fails at once | Pool name match, driver library, credentials, log messages |
Remove or disable debug samplers and heavy listeners before real load. They hold large amounts of data in memory and can slow the generator, which would distort your timings.
21Anti-patterns in Configuration
Mistakes that quietly distort tests, and the habits that prevent them.
Problem
Server names, ports and timeouts are typed into every sampler instead of one defaults element.
Why It’s Harmful
A change of environment means editing dozens of places, and one forgotten sampler keeps calling the old server. The test then mixes two environments and the results mean nothing.
Correct Approach
Set the address once in HTTP Request Defaults, driven by variables and properties, and leave the sampler fields empty.
Problem
All virtual users log in with the same account and search for the same word.
Why It’s Harmful
Caches answer almost every request, accounts may lock, and the database sees a trivial workload. The test shows speed that real users will never see.
Correct Approach
Feed each user unique data through a CSV Data Set Config with enough rows, and set the sharing and end-of-file behaviour on purpose.
Problem
No cookie manager is used, or several cookie managers sit in the same thread group.
Why It’s Harmful
Without one, sessions are lost and logged-in pages fail. With several, sessions behave unpredictably, producing random failures that are hard to reproduce.
Correct Approach
Use exactly one Cookie Manager per thread group at the group level, and choose the clear-each-iteration option deliberately.
Problem
User Defined Variables are used for values that should differ per user, or refer to variables defined later.
Why It’s Harmful
Every thread receives the same value, and references to later definitions stay unresolved, producing requests with literal variable names in them.
Correct Approach
Keep constants in User Defined Variables in the right order, and use data files, counters or extractors for per-user values.
Problem
Passwords, tokens and real customer data are stored in the plan and in data files, and the files are shared freely.
Why It’s Harmful
The files leak secrets and personal data. A load test turns into a security incident, and real accounts may suffer real side effects.
Correct Approach
Use synthetic test accounts, pass secrets at run time, store files in protected places and rotate test credentials.
Problem
A distributed test uses the same data file, counters and pool sizes on every worker without adjustment.
Why It’s Harmful
Workers collide on the same accounts and numbers, and pools multiply into far more connections than planned.
Correct Approach
Split data per worker, give each counter its own range, divide pool sizes and thread counts by the number of workers, and pass the same properties to all.
22Best Practices and Real-World Examples
A checklist you can follow, and four stories where Config Elements made the difference.
Best-practice checklist
Prefer a Config Element to a script
If a built-in element can do the job, use it. It is faster, clearer and easier to maintain.
Set shared values once
Use defaults, header managers and variables so that each fact lives in one place.
Respect scope and order
Place each element at the right level of the tree and remember that the nearest element wins.
Model sessions and caches on purpose
Choose cookie and cache behaviour to match the audience: first-time visitors, returning users, or a mix.
Plan data and end-of-file behaviour
Calculate the rows you need, add a margin, and decide what happens when data runs out.
Make the plan environment-neutral
Drive hosts, thread counts and durations through properties with safe defaults.
Protect secrets
Use synthetic accounts, pass credentials at run time and rotate them after use.
Verify with one thread first
Inspect real requests and variable values before scaling up to a large test.
Real-world stories
Migrating a test to a new environment in minutes
A team moved from a test environment to a pre-production one. Because the server, port and credentials were driven by variables that read properties, they changed three run settings and started the test. A neighbouring team with addresses typed into every sampler spent a full day editing, and still missed a few requests that hit the old server.
A cache setting that changed the story
A media site tested with the cache cleared every loop and found its content delivery layer overloaded at a modest user count. Analytics showed that most real visitors were returning users with warm caches. A second run with cache enabled showed a comfortable margin. Running both gave the business a worst-case number and a typical number, and the capacity plan used each in the right place.
Data that ran out unnoticed
A long test used a data file of a thousand accounts and a setting that let threads continue with the last value at the end. After the first hour, many users reused one account, the application locked it, and errors climbed. The report blamed the application until the team checked the end-of-file settings. Extending the data and stopping threads at the end gave a clean result.
One host hiding behind a load balancer
During a test of a load-balanced site, one server was saturated while the others were idle. Name resolution had cached a single address for the whole test run. Using the DNS Cache Manager to refresh and spread resolution brought the load evenly across the servers and removed a false capacity problem.
23Building a Faithful Virtual Browser with Config Elements
A real browser does many small things automatically. Config Elements let you copy the ones that matter.
When a person opens a web page, the browser quietly performs a long list of tasks. It resolves the host name, opens connections, sends headers, stores and returns cookies, reuses cached files, downloads images and scripts in parallel, and asks for compressed content. A JMeter thread does none of this unless you tell it to. The more of these behaviours you copy, the closer your virtual user is to a real one, and the more your load matches reality.
| Real browser behaviour | Config Element that copies it | Effect on the test |
|---|---|---|
| Remembers the login session | HTTP Cookie Manager | Pages that need a login work, and each user has a separate session |
| Reuses downloaded static files | HTTP Cache Manager | Fewer bytes and fewer requests on repeat visits |
| Sends identifying and format headers | HTTP Header Manager | Server treats the request like a real browser request |
| Downloads images, styles and scripts in parallel | HTTP Request Defaults with embedded resource options | Page load includes the downloads, with a limited number in parallel |
| Resolves host names through the system | DNS Cache Manager | Load spreads over all addresses of a name, or follows chosen addresses |
| Applies time limits to slow servers | Timeouts in HTTP Request Defaults | Stalled requests end as clear errors, not silent waits |
| Accepts compressed content | Accept encoding header in the Header Manager | Smaller responses and a realistic network load |
| Uses a different identity per person | CSV Data Set Config | Each user logs in and searches with different data |
The faithful-user starter kit
For a typical web application used through a browser, a strong starter kit placed at the thread group level contains five items. First, a defaults element with the server, the protocol, the timeouts and the embedded resource rules. Second, a header manager with the main headers copied from a real browser. Third, a cookie manager with a deliberate choice about clearing each loop. Fourth, a cache manager that matches the share of returning visitors. Fifth, a data element that gives each user unique credentials and search terms.
flowchart TD
V["Virtual user thread"] --> D["Defaults: server, timeouts, resources"]
V --> H["Headers: browser identity and formats"]
V --> C["Cookies: own session"]
V --> K["Cache: own saved files"]
V --> F["Data: own account and search terms"]
D --> R["Request that looks like a real browser request"]
H --> R
C --> R
K --> R
F --> R
Connection reuse
Browsers keep connections open and reuse them for many requests, which saves the cost of opening and securing a new connection each time. JMeter does the same by default for each thread when the server allows it, and the request defaults let you control this behaviour. If a test accidentally opens a new connection for every request, the cost of connection set-up, especially the secure handshake, appears in every response time and also loads the generator’s processor. When connect times in your results are unexpectedly high, check connection reuse before blaming the network.
When not to imitate the browser
Not every test needs a browser. If you test a back-end service called by other programs, copying browser cache and cookie behaviour may be wrong. Real service clients behave differently: they may keep no cookies at all, send tokens in headers, and never download images. Imitate the client that really calls the system, not the one that is easiest to imagine.
Copying every browser behaviour into a test of a pure service. The extra cache and embedded resource handling add memory use and complexity without changing the load that the service sees, and they can hide the real bottleneck behind unrelated downloads.
Building a virtual browser is like dressing an actor for a play. A costume that matches the role makes the performance believable. A costume from the wrong play, such as a king’s robe for a farmer, makes the audience, and your results, confusing.
Example: compression forgotten in headers
A team tested a content-heavy page and saw network usage twice as high as production. A comparison of headers showed that real browsers sent a header accepting compressed content, while the test did not. After adding that header through the header manager, the traffic matched production and the network was no longer the false bottleneck.
24Choosing Config Elements for Pages, Services and Databases
Different targets need different starter kits.
Because each type of system is used in a different way, each deserves its own selection of Config Elements. The table below gives a starting point, and the following sections explain the reasoning.
| Target | Elements to include | Elements to think twice about |
|---|---|---|
| Web application used in a browser | Defaults, header manager, cookie manager, cache manager, CSV data, DNS cache manager when load balanced | Large embedded resource pools if the test is about the main document |
| REST or other web service | Defaults, header manager with content type and token, CSV data, counter or random variable | Cookie and cache managers, unless the real client uses them |
| Database | JDBC connection configuration, CSV data, random variable for key selection | Pool size that differs from real application use |
| Secured service with client certificates | Keystore configuration, defaults, header manager | Handshake cost on the generator at high thread counts |
| File transfer or directory service | Protocol defaults, login config element, CSV data | Shared credentials for all users |
Web services
A service called by other programs usually needs fewer browser behaviours and more precise headers. The content type header is essential. An authorisation header, filled from a variable that holds a token captured at login, is typical. Data comes from a file or from counters and random values. Cookies often are not used at all, and a cache is irrelevant. This leaner kit also costs less memory per thread, allowing more threads on one generator.
Databases
For database tests, the central element is the connection pool, and the key design decision is its size relative to the thread count and to the application’s real limit. The data element supplies keys, such as customer numbers, that are real and spread across the table, so that the database cannot answer everything from memory. A random variable can pick from a range when the keys have no gaps.
Browser kit
Defaults, headers, cookies, cache, data and resolution settings. The richest set, closest to a real person.
Service kit
Defaults, precise headers, token handling and data. No browser extras.
Database kit
Connection pool, realistic keys and driver libraries on every machine.
Secure client kit
Keystore, certificates and attention to the processor cost of secure handshakes.
Mixed journeys
Many real journeys combine styles: a user opens pages in a browser, and the pages call services behind the scenes. In such a plan, use separate thread groups or controllers, each with its own kit. The page steps use the browser kit, and the background service calls use the service kit with their own headers and defaults. This keeps the cookie and header settings of one style from disturbing the other.
Name the real client
Decide who or what really calls the system: a browser, a mobile app, another service or a batch job.
List its behaviours
Write down headers, cookies, caching, connection use and data habits of that client.
Map each to an element
Choose the Config Element that copies each behaviour, and skip the ones the client does not show.
Verify against real traffic
Compare requests from your test with captured real requests. Fix any difference in headers, sizes or order.
Capture one real session from a browser or an app, and keep it next to your test plan as a reference. Whenever a result looks strange, compare your test’s request with the reference. Most surprising results end up in a header, a cookie or a data difference.
Example: a service test copied browser habits
A team tested a payment service with a browser kit that included a cache manager and embedded resource downloads. The service returned only structured data, so these settings did nothing useful, yet they consumed memory and complicated the report. Moving to a lean service kit allowed twice as many threads on the same machine and made results easier to read.
25Pre-Flight Checklist and Long-Term Maintenance
A test plan is a living asset. Keep its configuration healthy before every run and across releases.
Pilots never take off without a checklist, however many times they have flown. Performance testers benefit from the same discipline. Most failed test runs are caused not by the application, but by a forgotten setting: a data file not copied, a property not passed, a plugin missing on one machine. A short checklist before each run removes most of these surprises.
The pre-flight checklist
| Area | Question to ask | Why it matters |
|---|---|---|
| Target | Does the request details view show the intended server and port? | Prevents testing the wrong environment |
| Properties | Were all run settings passed to every machine? | Avoids workers running with defaults by mistake |
| Data files | Do they exist on every worker, with enough valid rows? | Prevents instant failures and data exhaustion |
| Data quality | Can every test account log in, and are none locked? | Avoids false errors blamed on the application |
| Sessions | Are cookie and cache settings as planned for this test type? | Keeps first-visit and repeat-visit tests apart |
| Timeouts | Are connect and response timeouts set sensibly? | Turns stalls into visible errors |
| Plugins and drivers | Are versions identical on all machines? | Avoids unknown elements and driver errors |
| Pools | Does the pool size match real application limits and the thread plan? | Prevents false queueing or false overload |
| Secrets | Are credentials passed safely and test accounts used? | Prevents leaks and real side effects |
| Debug items | Are debug samplers and heavy listeners removed? | Protects generator memory and timing accuracy |
A smoke run before the real run
Always run a short smoke test with a few threads, one or two loops, and the same configuration as the real run. Read a handful of real requests and responses in detail. This takes minutes and catches most configuration errors while they are cheap to fix. Only after the smoke run looks right should you scale up to the full load.
Smoke run with one thread
Confirm that every step works, headers are right, cookies persist and variables hold real values.
Small run with a few threads
Check that data rows are distributed as planned and that threads do not collide on accounts or counters.
Calibration run
Test the generators against a very fast endpoint, so that you know the machines can hold the planned thread count.
The real run
Start the full test, watch the live graphs, and note any configuration change in the test log.
Maintaining the plan over time
Applications change, and test plans must change with them. A new header becomes mandatory, a login flow adds a step, a host name moves, or a data field changes format. Because Config Elements hold shared settings in one place, most of these changes need only a small edit. To keep it that way, review the plan after each major release, remove elements that no longer apply, and keep the layered structure tidy.
Version the plan
Keep the plan and its data templates in version control, with a short note of every important change.
Document properties
List every property the plan reads, its default value and its purpose in a short readme beside the plan.
Prune unused elements
Delete or disable old elements. Unused elements confuse readers and may still affect requests in their scope.
Record the environment
Write down the JMeter version, plugin versions and machine sizes with every important result.
Leaving disabled or forgotten Config Elements in the plan for months. A forgotten header manager with an old token or an old defaults element with an outdated server can quietly change requests in its scope, and nobody remembers why results changed.
Example: an old header returned to haunt a test
A team reused a plan from the previous year. A forgotten header manager still sent an old version header, so the server routed all requests to a legacy path. Results looked strangely slow until someone compared the request details with real traffic. Removing the stale element restored normal behaviour, and the team added the pre-flight checklist to their routine.
26Troubleshooting: Symptoms, Causes and Fixes
Start from what you see and work towards the cause.
| Symptom | Likely cause | First check |
|---|---|---|
| Requests go to the wrong server | A sampler has its own server value overriding the defaults | Request tab and the sampler’s server field |
| Setting seems ignored | Element is outside the scope, or a nearer element overrides it | Position in the tree and neighbouring elements |
| Logged-in pages fail after login | Missing cookie manager or session cookie not stored | Cookie line in the request tab and set-cookie in the previous response |
| Login works on the first loop only | Cookies kept between loops | Clear-cookies-each-iteration option |
| Variable name appears in a request | Variable not defined yet or misspelled | Order of User Defined Variables and exact names |
| All users use the same data row | Sharing mode set per thread, or file has one row | Sharing mode and file contents |
| Errors grow late in a long test | Data ran out and values repeat or are empty | Recycle and stop-thread settings, file length |
| Strange characters in sent data | Wrong content encoding | Encoding in defaults and in the data element |
| Database samples fail instantly | Pool name mismatch or missing driver library | Pool variable name, driver on every machine, log file |
| Duplicate values across workers | Counters or data files not split per worker | Start values and file slices on each worker |
| Plan opens with unknown elements | Plugins missing on this machine | Installed plugins and versions |
A calm way to investigate
Reproduce with one thread
Remove load from the picture, and check that a single user behaves correctly.
Look at what was really sent
Read the request details of the failing sample and compare them with what you expected.
Check the nearest elements first
Look at the elements closest to the sampler in the tree, because they override those above.
Change one thing and rerun
Fix one suspected cause at a time, so you know which change solved the problem.
27Frequently Asked Questions
Quick answers to questions that come up in almost every project.
It is an element that prepares settings, data or shared behaviour for the samplers in its scope. It does not send requests or create results itself. Examples are HTTP Request Defaults, header and cookie managers, and the CSV Data Set Config.
Before every sampler in their scope, ahead of pre-processors, timers, the sampler, post-processors, assertions and listeners. The exception is User Defined Variables, which are processed once at the start of the test in the order they appear.
At the level of the tree where its effect should begin. Place broad settings at the test plan or thread group level, and exceptions inside controllers or beside single samplers. The element affects the samplers at and below its place in the tree.
JMeter combines them. When values clash, the element nearer the sampler generally wins, and values typed in the sampler itself win over any default.
A variable belongs to one thread and can differ per user. A property belongs to the whole JMeter process, is shared by all threads and can be set from the command line. Use properties for run settings and variables for user data.
One per thread group, placed at the group level. Several in one group can cause unpredictable session behaviour.
Use the all-threads mode when every thread should take a unique row, the thread group mode for separate user types, and the current thread mode when every user must read the whole file in order.
Probably because a sampler still has its own server value, which wins over the defaults. Clear the field in the sampler and confirm in the request details.
Use it when your real users have caches and your pages download many static files. Turn it off or clear it each loop for first-visit and worst-case tests. Keep the setting identical between tests that you want to compare.
Each worker has its own copy of every element and its own state. Data files must exist on each worker, counters and data pointers are independent, pools multiply, and properties must be passed to each machine.
It is risky, because the plan file holds them. Use synthetic test accounts, pass secrets at run time where you can, protect plan files and rotate test credentials.
Run with one thread and read the request details in the results tree. Use a debug sampler to list current variables, check scope and nearness, and read the JMeter log file for messages about the element.
28Summary and Key Takeaways
Config Elements are the preparation layer of a JMeter test plan. They supply defaults, headers, cookies, caches, credentials, data and connections to the samplers in their scope, and they do this before every sampler runs. Their power comes from three general ideas: scope decides which samplers they affect, the nearest element wins when settings clash, and User Defined Variables are the special case processed once at the start. Used well, they make plans short, realistic, portable and safe. Used carelessly, they produce silent mistakes such as wrong servers, shared accounts, lost sessions and leaked secrets.
Key Takeaways
- Prepare, do not act — Config Elements supply settings and data for samplers, and never send requests or create results themselves.
- Scope and nearness rule — an element affects the samplers at and below its place in the tree, and the nearest element wins when values clash.
- Mind the order — Config Elements run first for each sampler, while User Defined Variables run once at the start and cannot see later definitions.
- Choose realism on purpose — decide cookie and cache behaviour to match your audience, and remember that realism costs memory and CPU.
- Plan your data — size data files from threads and loops, pick the right sharing mode, and decide what happens at the end of the file.
- Remember distributed tests — every worker has its own copy and state, so split data, separate counters and divide pools and thread counts.
- Keep plans portable and safe — drive environments through properties, use synthetic accounts, and keep secrets out of shared plan files.