Using Gatling’s CSV Feeder to Drive Real‑World Load Tests
Learn how Gatling’s CSV feeder injects real data into virtual users, enabling realistic load tests. The article covers setup, usage, debugging, trade‑offs, and a step‑by‑step example.
19 Sept 2026, 07:45 UTC

Problem: Feeding Real Data Into Load Tests
When you want to simulate real users, you need realistic data for usernames, passwords, search terms, or any business‑specific field. Hard‑coding values or generating random strings wastes time and can mask issues that appear only with specific data patterns. Gatling’s CSV feeder lets you inject structured rows into each virtual user (VU) session, mapping columns to variables that can be used in URLs, headers, bodies, and assertions.
Thesis: The CSV feeder is the most flexible and efficient way to provide per‑user data in Gatling simulations.
Unlike manual session manipulation or custom feeders, the built‑in CSV feeder handles large files, supports multiple distribution modes, and integrates seamlessly with Gatling’s Expression Language (EL). Below we walk through a concrete example, explain the key knobs, and discuss trade‑offs.
1. Setting Up the Feeder
Place your data file in the src/test/resources folder of your simulation module. Gatling resolves paths relative to this location, so the following file structure works in most IDEs:
src\n└── test\n └── resources\n └── users.csv\n
The CSV must start with a header row. For example:
username,password,searchTerm
alice,Pa$$w0rd,scala
bob,Secret123,gatling
charlie,MyPass,loadtesting
Define the feeder in your simulation:
val userFeeder = csv("users.csv").circular
csv("users.csv")loads the file..circulartells Gatling to loop over rows; alternatives are.randomand.sequential.
2. Using Feeder Data in Requests
Feed the session into a scenario with feed(userFeeder). Each VU receives a row and the column names become session variables.
val scn = scenario("LoginAndSearch")
.feed(userFeeder)
.exec(http("Login")
.post("/login")
.formParam("username", "${username}")
.formParam("password", "${password}")
.check(status.is(200)))
.pause(1)
.exec(http("Search")
.get("/search?q=${searchTerm}")
.check(status.is(200)))
Notice the EL syntax ${columnName} used inside formParam and get. Gatling automatically casts each column value to a string, but you can coerce to other types if needed.
3. Verifying Feeder Injection
During development, add a debug step:
.exec(session => {
println("Session after feed: " + session)
session
})
Running the simulation prints the session map, showing the injected variables. After the request, you can inspect the report’s session column to confirm each VU used a distinct row.
4. Trade‑Offs and Limitations
- Per‑User Scope: By default, feeder rows are assigned per VU. If you need shared data across all users, you must explicitly store values in the session or use a custom feeder that returns the same row for every request.
- Large Datasets: Gatling streams CSV rows, but the initial compilation step still reads the file header and builds an index. Millions of rows can increase startup time and memory usage. Consider partitioning the file or using a database feeder for extremely large data sets.
- Type Mismatch: Columns containing numeric values used in string EL can cause runtime errors if not coerced. For example,
${age}in a URL must be cast with.asInt()if you later need it as an integer in a custom function. - Encoding: The file must be UTF‑8. Non‑UTF‑8 files may result in malformed session variables.
5. Actionable Checklist
- Place CSV in
src/test/resourcesand verify UTF‑8 encoding. - Define the feeder with the desired distribution mode.
- Feed the scenario and reference columns with
${columnName}. - Debug with
exec(session => println(session))to ensure correct injection. - Run a small test run; check the Gatling report’s session columns for expected values.
- For production runs, monitor startup time; if it becomes a bottleneck, split the CSV or switch to a database feeder.
By following these steps, you can harness Gatling’s CSV feeder to create realistic, data‑driven load tests that expose issues only visible under real‑world data patterns.
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.