The CSV Data Set Config in JMeter
How to give every virtual user their own username, password, search word or order number from a simple text file, how the file is shared between users, and how to avoid the traps that make test data quietly ruin results.
Imagine a school sports day where a hundred children must each collect a numbered bib before the race. If the teacher hands every child the same bib, number seven, chaos follows. Nobody knows who finished first, and the officials refuse to record the result. A load test has exactly this problem. If a hundred virtual users all log in with the same username, the website may block the duplicates, or it may answer every request from a fast stored copy, and your test then measures nothing real. Real users are different people, with different names, different passwords and different shopping baskets. In Apache JMeter, the element that hands each virtual user their own set of values from a text file is the CSV Data Set Config.
This guide teaches the CSV Data Set Config from zero. You do not need earlier JMeter knowledge. We begin with what test data is and why it matters, then look at what a CSV file is, then walk through every field on the element’s screen. After that we follow what happens inside JMeter when a line is read, how users share a file, what happens when the file runs out, and how to place the element correctly. The later chapters cover the topics that separate a careful engineer from a beginner: sizing the data, distributed testing, performance, privacy, debugging, patterns, and the mistakes that quietly distort results.
WWhat Is the CSV Data Set Config?
It is a JMeter element that reads lines from a text file and turns each piece of a line into a variable your test can use.
Starting with the basics
Apache JMeter is a free, open-source tool written in Java that measures how well a system behaves when many users use it at the same time. This is called load testing or performance testing. A JMeter test is arranged as a tree called a Test Plan, and the pieces inside the tree are called test elements. Each virtual user is a thread, a small worker that walks through the tree independently of the others.
A Sampler sends one request, such as an HTTP call, and records the answer. A Config Element supplies settings or data to the samplers around it. A variable is a named value that JMeter swaps into a field at run time. You write a variable by putting its name between a dollar sign and curly brackets. The CSV Data Set Config is a config element whose job is to fill variables with data from a file.
What it really does
You point the element at a text file. Each line of the file is one record, and the values on the line are separated by a chosen character, usually a comma. You give names to the columns. Then, whenever a virtual user starts a new pass, the element reads the next line and stores its values in variables for that user. Samplers can then write those variable names into their fields, and JMeter replaces them with the real values.
Think of a bank queue where a clerk hands out numbered slips from a roll. Each customer takes the next slip and carries it to the counter. The roll is the CSV file, the clerk is the CSV Data Set Config, and the slip number the customer carries is the variable value. Nobody gets the same slip twice, unless the roll runs out and the clerk decides to start a fresh roll.
Why it matters so much
Almost no real application can be tested honestly with a single set of values. Logins must differ. Search words must vary. Orders need unique references. If the data is wrong, the test is measuring a fantasy: errors from duplicates, or unrealistic speed from caches. A test with careful data behaves like a crowd of different people. A test with careless data behaves like one person cloned a thousand times.
The CSV Data Set Config reads one line from a file for each virtual user for each pass, and puts the values of that line into variables. It is the standard way to give a JMeter test varied, realistic input.
TThe Test Data Problem
Before learning the element, it helps to see exactly what goes wrong when a test has no varied data.
Four things that go wrong
Duplicate logins rejected
Many systems allow one active session per user. The second login with the same name kicks out the first, and your users fight each other.
Caches answer everything
When a thousand users ask the identical question, the server answers from a fast stored copy. Real, varied questions are much slower.
Unique fields repeat
Order numbers, email addresses and booking references must be unique. Repeats cause errors that have nothing to do with capacity.
One hot record
If every user reads the same row in the database, that row becomes a bottleneck that real traffic would never create.
Why caches fool you
A cache is a fast memory where a system keeps answers it has already worked out, so it can reuse them. When a thousand users search for the same word, the system works the answer out once and then hands back copies. A real crowd searches for thousands of different words, and most of those answers must be worked out from scratch. A test that always asks the same question therefore measures the speed of the cache, not the speed of the system. The report looks wonderful and predicts nothing.
The value of realistic spread
Real data has natural spread. Some products are popular and many are rarely viewed. Some users have large carts and many have small ones. A good test file reflects that spread. It does not need to be perfect, but it should not be absurdly narrow either.
Testing a library by asking a thousand people to borrow the same single book tells you only how fast one shelf can be reached. Testing it with a thousand different requests across the building tells you how the whole library copes.
A test that passes with a single repeated record can fail badly in production, because production traffic is varied. Varied data is not a luxury. It is part of what makes a result believable.
CCSV Files in Plain Words
CSV is one of the simplest file formats there is, and a few small details decide whether JMeter reads it correctly.
What CSV means
CSV stands for Comma Separated Values. It is a plain text file where each line is one record and the values on that line are separated by commas. You can open it in any text editor or in a spreadsheet program. The first line often holds the names of the columns, and the lines after it hold the data.
| username | password | city | product_id |
|---|---|---|---|
| testuser001 | Pass-001-x | Delhi | P1024 |
| testuser002 | Pass-002-x | Mumbai | P3310 |
| testuser003 | Pass-003-x | Chennai | P7781 |
The table above shows how a data file looks when viewed as a grid. In the actual file, each row is a line and the cells are separated by the delimiter. When JMeter reads it, the first row of data fills the variables named username, password, city and product_id for one user, the second row for another user, and so on.
Small details with big effects
Delimiter
The character that separates values. A comma is the default, but a semicolon, a tab or a pipe is also common, especially when the data itself contains commas.
Quotes
Values that contain the delimiter, such as an address with commas, are often wrapped in double quotes so they count as one value.
Encoding
The way characters are stored in bytes. UTF-8 is the safest choice, because it handles accents and many languages.
Empty lines
A blank line at the end of the file is read as a record with empty values, which can cause strange requests.
Hidden characters
Some editors add an invisible marker at the start of a UTF-8 file. It can attach itself to the first value and make the first column name or first value look wrong.
Create and check your data file in a plain text editor, not only in a spreadsheet program. Spreadsheets sometimes change values quietly, such as turning long numbers into scientific notation or removing leading zeros from product codes.
WWhere the Element Sits in a Test Plan
The position of the CSV Data Set Config in the tree decides which users and which samplers can see its variables, and how often it reads a new line.
A typical tree
A test starts with the Test Plan and a Thread Group, which controls how many virtual users run and how many times each one repeats. Config elements such as the CSV Data Set Config are normally placed near the top of the Thread Group, so every sampler beneath them can use the variables.
flowchart TD
A[Test Plan] --> B[Thread Group]
B --> C[CSV Data Set Config users]
B --> D[HTTP Request Defaults]
B --> E[HTTP Cookie Manager]
B --> F[HTTP Request Login]
B --> G[HTTP Request Search]
B --> H[Listener]
Scope in one idea
Scope means which samplers an element affects. An element affects its own level and everything beneath it, like a notice pinned on one floor of a building: everyone on that floor sees it. A CSV element placed under the Thread Group is visible to every sampler in the group. A CSV element placed under one controller is visible only to samplers in that controller.
The order JMeter runs things
For each sample, JMeter applies config elements first, then pre-processors, then timers, then the sampler runs. After the response, post-processors, assertions and listeners follow. The CSV element, as a config element, has its values ready before the sampler fills in its fields. This is why variables from the file can appear in the very first request of a pass.
Picture a restaurant where the waiter first receives a printed order slip from the cashier and then goes to the kitchen. The slip is the config element. It is handed over before any cooking starts, so the kitchen always has the details it needs.
If you place the CSV element below a sampler in the tree, that sampler cannot use its variables on the first pass. Place data elements above the samplers that need them.
TTour of the Element’s Screen
The screen has a handful of fields. Each one answers a simple question about the file and about what to do with it.
The fields
| Field | What it does | Common mistake |
|---|---|---|
| Name and Comments | A label and a free note for readers of the plan | Leaving default names when several data files are in use |
| Filename | The path of the data file. Relative paths are read from the folder of the test plan | Using a full path from your own laptop that does not exist on another machine |
| File encoding | How characters in the file are decoded, such as UTF-8 | Leaving it empty and getting odd characters with accented text |
| Variable Names | Comma-separated names for the columns, in order | Names in the wrong order, so values land in the wrong variables |
| Ignore first line | Skips the first line when names are typed into the field | Forgetting it, and sending the header text as data |
| Delimiter | The character that separates values, with a special form for tab | A comma delimiter for a file that uses semicolons |
| Allow quoted data | Treats text inside double quotes as one value | Leaving it off when values contain commas |
| Recycle on EOF | Go back to the first line when the file ends | Leaving it on and reusing data that must be unique |
| Stop thread on EOF | End the user when the file ends, if recycling is off | Expecting it to work while recycling is on |
| Sharing mode | Decides which users share the same position in the file | Choosing the default without thinking about it |
How to read the Filename field
If the filename is just the name of a file, such as users.csv, JMeter looks for it next to the test plan. This is convenient, because you can keep the plan and its data together in one folder and move them as a pair. An absolute path, which starts from the root of a drive, works but ties the plan to one machine. The filename field also accepts a variable or a property, so the path can be chosen when the test is launched. This lets one plan use a small file for a quick check and a large file for the full run.
Put the plan and its data files in the same folder, use relative paths, and commit them together. A plan that works on your laptop and a build server alike saves hours of confusion.
NNaming the Columns: Variable Names and the Header Line
The element needs to know what to call each column. There are two ways to tell it, and each has its own rules.
Way one: type the names into the element
In the Variable Names field, you type the names of your columns in the same order they appear in the file, separated by commas. If your file has username, password and city, you type those three names. When you do this, the first line of the file is treated as data unless you also set the Ignore First Line option to true. If your file does have a header row and you forget the option, the header text is used as the first record, and your first virtual user logs in with the literal word “username”.
Way two: let the file’s first line supply the names
If you leave the Variable Names field empty, JMeter reads the first line of the file and uses it as the list of column names. This is neat, because the file describes itself, and you can add a column later without editing the plan. The first record of real data then starts from the second line.
Names typed in the element
- The plan clearly shows which variables exist
- Works with files that have no header line
- You can rename variables without touching the file
Names taken from the file
- The plan does not show the variable names, so readers must open the file
- A typo in the header silently creates a differently named variable
- A hidden character at the start of the file can corrupt the first name
Naming rules that save pain
Keep names simple
Use letters, numbers and underscores. Avoid spaces and special symbols.
Mind the case
Variable names are case sensitive. Username and username are two different variables.
Avoid clashes
Do not reuse a name that another element, such as an extractor, also fills. They would overwrite each other.
Match the count
Make the number of names equal to the number of columns, or values will shift or go missing.
If a request shows a strange value such as the text of a column heading, or an empty value where a name should be, the first suspect is the header handling. Check the Ignore First Line option and the order of the names.
HHow the Element Works Internally
Behind the scenes, the file is opened once and handed out one line at a time. Seeing the steps explains most surprises.
Step by step
sequenceDiagram
participant T as Virtual User Thread
participant C as CSV Data Set Config
participant F as Data File
participant S as Sampler
T->>C: A new pass is starting
C->>F: Ask for the next line
F-->>C: One line of text
C->>C: Split the line into values
C-->>T: Store values in this user's variables
T->>S: Run the sampler
S->>S: Replace variable names with the values
Open the file once
At the start of the test, JMeter opens the file and keeps a position marker. It does not load the whole file into memory.
Wait for a new pass
Each time the part of the tree that contains the element begins a new iteration, it signals the element.
Read the next line
The element takes the next line at the shared position, and moves the position forward.
Split and store
The line is cut at each delimiter, and each piece is placed in the variable with the matching name, for that user only.
Samplers use the values
When a sampler runs, JMeter replaces each variable name in its fields with the stored value.
Variables belong to each user
The values are stored in the variable space of the thread that asked. Each virtual user therefore has its own copy of username, password and the rest. User one’s login cannot be changed by user two reading a new line. This is why a hundred threads can each hold a different name at the same instant.
Order is not guaranteed
Threads ask for lines in whatever order they happen to reach the element. Thread seven may arrive before thread three. If you need a particular user to always get a particular line, the plain shared mode does not promise that. Later chapters show how to arrange that when it matters.
Think of a photocopier tray of numbered tickets at a government office. Citizens walk in at different times and each takes the top ticket. The tickets are always taken in order, but which citizen gets which ticket depends on who arrives first.
Because lines are read one at a time, even very large files are cheap to use. A file with a million rows costs almost no memory. The limit is the time to prepare the data and the disk to hold it, not JMeter’s reading.
SSharing Modes: Who Shares the Same Position
The sharing mode decides whether users take lines from one shared pile, from separate piles, or from each other’s piles.
The four choices
| Mode | What happens | Best used for |
|---|---|---|
| All threads | Every user in the whole test shares one position. Each line is handed to exactly one user at a time. | Unique logins, unique order references, normal cases |
| Current thread group | Each Thread Group has its own position, so groups do not take lines from each other. | Different user types, each with its own file or section |
| Current thread | Every user reads the file from the top, separately. | Giving every user the same list, such as the same product set |
| Identifier | Users that share the same chosen identifier share a position. Others do not. | Custom groupings that cut across Thread Groups |
flowchart TD
A[Need data for each user] --> B{Must each user get a different row}
B -->|Yes| C[All threads]
B -->|No| D{Should each user walk the whole file}
D -->|Yes| E[Current thread]
D -->|No| F{Separate pools per user type}
F -->|Yes| G[Current thread group or Identifier]
F -->|No| C
Seeing the difference
Suppose a file has five lines and three users each read two lines. With All threads, the six reads draw lines one to five and then the sixth read needs a recycled first line. Every user gets a different line until the file wraps. With Current thread, every user reads lines one and two, so all three users see exactly the same data. The same file, with the same plan, behaves very differently depending on this single setting.
Picture three students and one shared textbook. In “All threads” mode, they pass one book around and each reads whatever page the book is on. In “Current thread” mode, each student has a personal copy and reads from page one. In “Current thread group” mode, each class has its own book that its students pass around.
Two elements, one file
When two CSV elements point to the same file with the same sharing setting, they may end up drawing from a shared position. If they have different variable names, each one then consumes lines that the other would have used, and neither user sees the full set. If you need the same file read twice for two different purposes, use different sharing identifiers, or make a second copy of the file.
The default mode, All threads, is right for most tests. The trouble starts when a test has several Thread Groups, each expecting to start from the first line. In that case, choose Current thread group, or the groups steal rows from each other.
WWhen the File Runs Out
Every file ends. What JMeter does at that moment is under your control, and the wrong choice causes some of the most confusing test failures.
The two settings that decide
Two options work together. Recycle on EOF answers the question “when the file ends, should I go back to the first line?” EOF stands for end of file. Stop thread on EOF answers “if I am not recycling, should the user stop?” Stop only has an effect when recycling is off.
flowchart TD
A[Reached end of file] --> B{Recycle on EOF}
B -->|True| C[Go back to the first line]
B -->|False| D{Stop thread on EOF}
D -->|True| E[This user stops]
D -->|False| F[Variables get the text EOF marker]
The three outcomes
Recycle on
The file starts again from the top. The test never runs out of data, but values repeat, which is harmful when they must be unique.
Recycle off, stop thread on
A user that finds no more data ends quietly. The test gradually loses users, which can be exactly what you want for a one-time data set.
Recycle off, stop thread off
The variables are filled with a special marker, shown as <EOF>, and the user carries on. Requests are then sent with that marker as the value.
Choosing on purpose
Values may repeat safely
For search words and product viewing, recycling is fine and keeps the load going.
Values must be unique
For new accounts and new orders, turn recycling off and stop the thread, so no duplicates are ever sent.
You want to spot shortages
Leaving the flag mode on makes the marker appear in requests and failures, which proves the data was too small, though it makes a messy test.
A test runs fine for ten minutes, then errors suddenly appear and climb. The file had fewer lines than the test needed. Either it wrapped and started repeating unique values, or it ran out and began sending the end-of-file marker. Always compare the number of rows with the number of reads the test will perform.
UUsing the Variables in Samplers
Reading data is only half the job. The values must land in the right fields of the right requests.
Where variables can go
You can use a variable almost anywhere you can type text in a sampler. Write the variable’s name between a dollar sign and curly brackets, and JMeter replaces it with the value at run time. Common places include the path of an HTTP request, the Parameters table, the Body Data for a JSON or XML request, header values, and assertions that check for expected text.
| Where | What you might put there | Example idea |
|---|---|---|
| Parameters table | Form values such as login name and password | Name and password boxes use the file’s username and password variables |
| Path | A product or order identifier inside the address | The product page path ends with the product_id variable |
| Body Data | Values inside a JSON request body | A payment request with an account reference from the file |
| Header Manager | A token or language preference per user | A language header chosen per row |
| Assertion | Expected text that depends on the row | The page must show the city from the file |
Combining file data with captured values
Many flows mix two sources of data. The file gives the starting values, such as the username and password. The server then returns changing values, such as a session token, and an extractor, a post-processor that reads a value out of a response, stores them in another variable. The next request uses both: the name from the file and the token from the extractor. Keep the two sets of variable names different so neither overwrites the other.
flowchart LR
A[CSV file row] --> B[Username and password variables]
B --> C[Login request]
C --> D[Server returns token]
D --> E[Extractor stores token variable]
E --> F[Next request uses token and city]
A --> F
When a variable is not found
If you misspell a variable name in a sampler, JMeter does not stop. It leaves the text of the variable reference in place, so the server receives something like a dollar sign and the literal name. The request then fails in a confusing way. If requests seem to contain strange text that looks like a variable, compare the spelling in the sampler with the name in the element, including upper and lower case.
Run one user and look at the actual request in a results viewer. The viewer shows the real values after replacement, which proves the data reached the right place.
PPlacement, Iterations and Controllers
The element reads a new line each time the part of the tree that holds it begins a new pass. So where you place it decides how often the data changes.
Thread Group level
If the element sits directly under the Thread Group, a new line is read at the start of each pass of the whole scenario. Every sampler in that pass sees the same row. This is the right choice when one pass represents one user doing one complete journey, such as logging in, searching and checking out with one set of details.
Inside a Loop Controller
A Loop Controller repeats the elements beneath it a set number of times. If the CSV element sits inside it, a new line is read on every pass of that inner loop. This is right when each repetition should use fresh data, such as adding ten different products to a cart, one per pass.
flowchart TD
A[Thread Group] --> B[Login request]
A --> C[Loop Controller 5 passes]
C --> D[CSV Data Set Config products]
C --> E[Add To Cart request]
A --> F[Checkout request]
Comparing the placements
| Placement | New line read | Good for |
|---|---|---|
| Under the Thread Group | At the start of each scenario pass | One identity per user per journey |
| Inside a Loop Controller | On every pass of that loop | A different item on every repetition |
| Inside a Once Only Controller | Only on the first pass of the loop it sits in | Data needed just for a setup step |
| Inside an If Controller | Only when the condition lets the pass in | Data for an optional branch |
Two files, two jobs
A common design uses two CSV elements. One, at the top of the Thread Group, holds the credentials, one row per user. Another, inside the loop, holds the products, one row per repetition. They have different variable names and different files, so they never collide.
Imagine a canteen where every student first receives a meal card, and then collects a different dish at each counter. The meal card is read once, at the entrance. The dish choice is read again at every counter. The two are separate pieces of data, handed out at different moments.
Ask yourself, “How often should this value change?” Place the element in the part of the tree that starts a new pass at exactly that rhythm.
SSizing and Creating Data Files
A data file that is too small is one of the most common causes of unreliable tests. A little arithmetic, done early, prevents it.
How many rows do you need?
The number of rows needed depends on how many reads the test will perform. Each read happens once per pass, per user, at the placement of the element. So the formula is the number of users, times the number of passes at that level, times the loop count if the element is inside a loop.
| Users | Scenario passes | Loop passes | Element at | Rows needed for unique data |
|---|---|---|---|---|
| 100 | 1 | not used | Thread Group | 100 |
| 100 | 5 | not used | Thread Group | 500 |
| 100 | 5 | 10 | Inside the loop | 5,000 |
| 2,000 | 10 | 20 | Inside the loop | 400,000 |
For tests that run for a set time rather than a set count, estimate from the request rate and the duration. If you expect fifty logins per minute for sixty minutes, you need three thousand unique accounts, and more if you want a safety margin.
Creating the data
Spreadsheet
Quick for small files. Save as plain CSV and double-check that numbers and codes were not altered.
A small script
A few lines of any language can generate thousands of predictable accounts with names and numbers in a pattern.
Database export
A query against a test database gives real-shaped product and customer ids that truly exist.
Production-shaped, anonymised
Statistics from real traffic can shape the spread, while all personal details are replaced with fake ones.
flowchart LR
A[Work out rows needed] --> B[Generate or export the data]
B --> C[Create the accounts in the test system]
C --> D[Verify a sample by hand]
D --> E[Save as plain UTF-8 CSV]
E --> F[Place the file next to the plan]
The data must exist in the system
A file full of usernames is useless if those users do not exist in the system under test. Test accounts must be created ahead of time, with the same passwords as the file, and product ids must refer to products that really exist. A frequent beginner failure is a perfect plan sending a thousand logins to accounts that were never created, producing a thousand errors that look like a broken system.
Pick a handful of rows from the file and try them by hand in a browser. If they do not work for you, they will not work for JMeter.
DData Files in Distributed Testing
When one machine cannot generate enough load, JMeter spreads the plan over several machines. This changes how data files behave.
What distributed testing is
In distributed testing, one controller machine commands several load generator machines. Each generator runs a full copy of the plan with its own set of virtual users. The generators then send traffic to the system under test, and send their results back to the controller.
flowchart TD
C[Controller] --> G1[Load Generator 1 with users part 1]
C --> G2[Load Generator 2 with users part 2]
C --> G3[Load Generator 3 with users part 3]
G1 --> T[System Under Test]
G2 --> T
G3 --> T
The file is read on each generator
Each load generator reads the file from its own disk. JMeter does not send the controller’s file to them. If the file is missing on a generator, the test fails there. Relative paths are resolved on each generator, so the file must sit in the same relative place. Absolute paths from your own computer will rarely exist on the generators.
The duplicate trap
If every generator has a copy of the same complete file, every generator starts at line one, and the same line is used by one user on each machine at the same time. With five generators, five users may log in with the same account together. The fix is to split the data: give each generator its own slice of rows, with no overlap, or use a pattern in the data that includes the generator’s identity.
Divide the rows
If you need ten thousand unique accounts over five generators, give each generator two thousand different ones.
Name the files the same
Use the same file name on every generator, so the plan needs no change, but fill each with its own slice.
Check before starting
Confirm each generator has the right file with the right rows and that no rows are shared.
Divide the users too
The number of threads in the plan applies per generator, so total users equal threads times generators.
Automation tools can copy a different slice of the data to each machine just before the run. That removes the manual step where mistakes creep in.
PPerformance and Scalability
The element itself is light. The trouble comes from the size of the data and from how the file is used.
Cheap to read
JMeter reads the file line by line as needed and does not hold it all in memory. A file with a few lines and a file with a few million lines behave almost identically while the test runs. The cost of reading a line is tiny compared with the cost of sending a request over a network.
Where the cost does appear
Very large files
Huge files take disk space on every load generator and take time to copy before the run.
Large values
If a column holds a big block of text, such as a long JSON body, each request carries it, and the generator’s network link may become the limit.
Large variables
Every user holds its own copy of the values. Huge values multiplied by thousands of users use real memory.
Shared reading
With one shared position, threads briefly take turns to read a line. At extreme thread counts this is still tiny, but it is shared work.
Keeping the file local
A data file placed on a slow shared network drive makes every read depend on that drive. Copy the file to the load generator’s own disk before the run. It removes a source of random delays that would otherwise show up as odd pauses in the test.
Think time still matters
Varied data does not replace realistic pacing. A loop that reads a new line and fires a request with no pause still floods the server. Use timers to keep each user’s pace human, so that the load the test creates matches the load you want to study.
Do not store enormous request bodies in a CSV column when a smaller template with a few varying fields would do. Build the body in the sampler and let the file supply only the parts that change.
SSecurity, Privacy and Responsible Data
A data file often holds usernames and passwords. It deserves the same care as any other sensitive document.
Never use real people’s data
Do not fill test files with real customers’ names, emails, phone numbers or card details. Data protection laws in many countries, including India, the European Union and others, place strict duties on how personal data is stored and used, and a load test file copied onto laptops and shared drives can easily break them. Use made-up people, made-up numbers and test accounts created just for this purpose. Where a test needs data shaped like real data, produce an anonymised version in which every identifying detail has been replaced.
Use test accounts
Create dedicated users with limited rights, so a leak of the file gives away nothing valuable.
Protect the file
Keep it in a folder only the test team can read, and never attach it to open emails or public repositories.
Clean up afterwards
Delete copies from load generators when the work ends, and remove test accounts that are no longer needed.
Check the results
Result files may record request values. Treat them as sensitive too, and save fewer fields where possible.
Passwords in plain text
A CSV file stores passwords as plain text. That is acceptable only for throwaway test accounts in a test environment. Never place a real production password in such a file. If the system supports test tokens that expire quickly, prefer them, and generate them just before the run.
Test only what you are allowed to test
Loading a system with thousands of logins from varied accounts can look exactly like a credential-stuffing attack, where criminals try many stolen passwords. Always have written permission, test in an environment you own or have been given, and warn the operators of the system before a run so that security tools and staff do not react as though it were a real attack.
Confirm that the data contains no real personal details, that the accounts are test accounts, and that the people who run the target system know about the test.
MMonitoring, Logging and Debugging Data Problems
Data problems are quiet. The test runs, the numbers appear, and only careful looking shows that the wrong values were sent.
The debugging toolkit
View Results Tree
Shows the real request with the values after replacement. The quickest proof that data landed in the right field.
Debug Sampler
Prints all current variables for the user, so you can read each column’s value on this pass.
Response Assertion
Fails a sample when the page does not show the expected user-specific text.
JMeter log
Records file problems, such as a file that could not be found or opened.
Common symptoms and their usual causes
| Symptom | Likely cause |
|---|---|
| Requests contain the literal variable text | The variable name is misspelt, or the element is placed below the sampler |
| First user logs in with the word “username” | The header line was read as data |
| Values land in the wrong fields | The names are in a different order from the columns, or the delimiter is wrong |
| Errors begin after some minutes | The file ran out and recycled or began sending the end-of-file marker |
| Many users log in as the same person | Sharing mode set to current thread, or each generator uses the same full file |
| Strange characters in names | Wrong file encoding or a hidden marker at the start of the file |
| Empty values in some requests | A blank line at the end of the file, or fewer values than names on a row |
| Test fails to start with a file error | The path is wrong on this machine |
A reliable routine
Run one user, one pass
Look at the request and confirm the first row of data appears exactly.
Run three users
Confirm that each user gets a different row and no row is skipped.
Force the end
Use a file with only a few rows and watch the end-of-file behaviour, so it is no surprise later.
Scale slowly
Raise users and passes in steps, watching errors at each step.
DDesign Patterns and Anti-patterns
Experienced engineers use a few reliable data designs and avoid a handful of tempting shortcuts.
Patterns that work
One file per kind of data
Keep users, products and search words in separate files, each with its own element and clear variable names.
Plan and data together
Store files next to the plan and use relative paths, so the pair moves together.
File name from a property
Choose the file at launch time, so one plan serves small checks and large runs.
Pre-created accounts
Create test users in the target system before the run, from the same source as the file.
Slice per generator
Give each load generator its own non-overlapping part of the data.
Assert on user-specific text
Check that the response mentions the row’s own value, proving the right user was served.
Anti-patterns to avoid
What people do
They use ten usernames for a thousand users and leave recycling on.
Why it hurts
Many users share one account. Systems that allow one session per user log people out, and caches answer repeated questions, so results are unreal.
Do this instead
Provide at least as many unique rows as there are concurrent users, and more if passes need new data.
What people do
They type an absolute path from their own laptop into the Filename field.
Why it hurts
The plan fails on every other machine, including the load generators and the build server.
Do this instead
Use a relative path and keep the data beside the plan, or supply the path as a launch property.
What people do
They paste real customer data into a test file.
Why it hurts
It risks a privacy breach and breaks data protection rules, and any leak of the file harms real people.
Do this instead
Use made-up or properly anonymised data and dedicated test accounts.
What people do
They copy the same full file to every load generator.
Why it hurts
Every generator uses the same early rows at the same time, so many users share an identity and unique values collide.
Do this instead
Split the data so each generator gets its own slice with no overlap.
BBest Practices and Common Mistakes
These are the habits that experienced performance engineers repeat on every project, and the slips that beginners make again and again.
Best practices checklist
| Area | Do this | Why |
|---|---|---|
| Sizing | Calculate the rows needed before building the file | Prevents running out of data mid test |
| Location | Keep the file beside the plan with a relative path | Makes the plan portable |
| Format | Save as plain text in UTF-8, without a hidden start marker | Avoids strange characters |
| Columns | Match variable names to columns in order | Stops values landing in the wrong place |
| Header | Decide clearly between a typed list and a header line | Avoids reading the header as data |
| Ending | Choose recycle or stop on purpose | Protects unique data and shows shortages |
| Sharing | Pick the sharing mode deliberately | Controls who sees which rows |
| Accounts | Create every test account before the run | Avoids a flood of avoidable failures |
| Privacy | Use made-up data and protect the file | Respects people and the law |
| Checking | Run a tiny trial and read the real requests | Proves the data flows correctly |
Common mistakes
- Forgetting to set Ignore First Line when a header row is present and names are typed into the element.
- Leaving a blank line at the end of the file, which becomes a record of empty values.
- Assuming that threads receive rows in a fixed order, when the order depends on who arrives first.
- Placing the element below the sampler that needs its variables.
- Running two Thread Groups on the default sharing mode and finding that they steal rows from each other.
- Using the same variable name in the CSV element and in an extractor, so they overwrite each other.
- Saving the data file from a spreadsheet and losing leading zeros or turning long numbers into scientific notation.
- Copying the same complete file to every load generator.
Open the data file in a plain text editor, look at the first and last lines, count the rows, then run one user and read the request. These two minutes catch most data mistakes.
RReal-World and Industry Examples
Here is how teams use the CSV Data Set Config in different kinds of systems. These are illustrative patterns that show the kind of scale and care involved, not descriptions of any company’s private tooling.
Online shopping at sale time
Large shopping platforms such as Flipkart or Amazon see huge spikes during sale events, with enormous numbers of different shoppers searching for different things. A test for such an event uses one file of shopper accounts, one file of search words reflecting popular and rare items, and one file of product ids. The accounts file is read once per user per journey, and the products file is read inside a loop so each pass adds a different item. Unique order references come from a function, and the accounts are created in advance.
A bank’s payment interface
A bank testing a payment service needs thousands of distinct, valid but fake accounts. A file lists source accounts, destination accounts and amounts that follow a realistic spread, such as many small payments and a few large ones. Unique payment references come from a unique id function so that duplicate checks do not interfere. Only synthetic data is used, the file is stored in a protected folder, and result files are cleaned up after the run.
A streaming service’s catalogue
Video services such as Netflix or Spotify serve a long catalogue where a few titles are extremely popular and most are rarely played. A test file lists titles with repeats in proportion to their popularity, so the popular ones appear many times and the rare ones appear once. Reading this file in a loop reproduces realistic caching behaviour, because the hot titles are served from fast caches and the rare ones must be fetched from slower storage.
A ride-booking surge
Ride-hailing companies such as Uber face sudden bursts when events end. A test uses a file of pickup and drop-off coordinates spread across a city, with some areas appearing more often to imitate busy districts. Each virtual rider reads a new pair per booking. Several Thread Groups, one for riders and one for drivers, use separate files and the sharing mode of the current thread group so they do not take rows from each other.
A government or school portal at a deadline
Portals for tax filing, admissions or results face a flood of different citizens in the last hours before a deadline. A test uses a file of applicant identifiers and form values created by a script, with stop thread on end of file so the test gradually winds down as the unique applicants are used up, which matches how a real, finite crowd behaves.
What these examples share
In every case, the data file is designed with the same care as the plan. The size is calculated, the spread resembles reality, the accounts exist, the privacy rules are respected, and the end-of-file behaviour is chosen on purpose.
TTrade-offs, Limits and Alternatives
The CSV Data Set Config is the everyday workhorse for test data. It has clear edges, and other tools fill the gaps.
Advantages
- Simple, readable files that anyone can edit
- Reads line by line, so huge files cost almost no memory
- Flexible sharing modes for different test shapes
- Works the same in single machine and distributed runs
- Free, built in and well understood by most teams
Disadvantages
- Reads rows in order, with no built-in random choice
- Data must be prepared in advance and exist in the target system
- Files must be copied to each load generator
- No built-in way to give a particular user a particular row
- Plain text files expose sensitive data if not protected
Alternatives and complements
Counter element
Produces an increasing number, ideal for building unique names such as user001, user002.
Random Variable and functions
Produce random numbers and strings, handy for search words, amounts and references.
JDBC Request
Reads data straight from a test database, so rows are always valid, at the cost of extra load and complexity.
Random CSV data set plugins
Community add-ons that read rows in random order, useful when order must not matter.
Values from earlier responses
Extractors capture ids returned by the system itself, so the data is always real and current.
Order and randomness
Because the element reads in order, a file sorted by popularity or by name gives a predictable and possibly biased sequence. If the order must not influence the test, shuffle the file before the run. Shuffling a file in advance is simple and removes any hidden pattern, such as all the users from one city coming first.
Static data versus live data
A file is a snapshot. If the system’s real data changes between the day the file was made and the day of the test, rows may become invalid: products withdrawn, accounts locked, prices changed. For long-lived test suites, regenerate the file regularly or pull data from the system itself at the start of the run.
A CSV file is like a printed guest list for a party. It is quick to use and easy to read. But it only reflects who was invited at the time of printing. If guests cancelled or new ones were added, the printed list can lead the doorman astray.
FFrequently Asked Questions
Short, direct answers to the questions people ask most often about the CSV Data Set Config.
SSummary and Key Takeaways
The CSV Data Set Config turns a crowd of clones into a crowd of different people. Careful use of it separates believable tests from fantasies.
Key Takeaways
- It feeds variables from a file. One line is read per user per pass, split by the delimiter, and stored in variables for that user.
- Name the columns carefully. Type the names and ignore the header line, or let the first line supply them, and keep names simple, matched in order and different from other variables.
- Choose the sharing mode on purpose. All threads gives unique rows, current thread gives everyone the same list, and thread group or identifier gives separate pools.
- Decide what happens at the end of the file. Recycle when repeats are fine, stop the thread when values must be unique, and never ignore the end-of-file marker.
- Placement sets the rhythm. Under the Thread Group the data changes once per scenario pass, and inside a Loop Controller it changes on every loop pass.
- Size and prepare the data. Do the arithmetic, create the accounts in the target system, split files across load generators and check by hand.
- Protect people and systems. Use made-up data, secure the files, test only what you are allowed to test, and warn the owners before a heavy run.