Using Gatling CSV Feeders for Data‑Driven Load Tests
Learn how to configure a CSV feeder in Gatling to give each virtual user unique credentials, understand memory limits, and avoid common pitfalls.
26 Feb 2026, 15:43 UTC

Why use a feeder in Gatling
When a load test needs each virtual user (VU) to send distinct data—such as a username, password, or product ID—you attach a feeder to the scenario. The feeder pulls the next record from an external source for every iteration, preventing all VUs from using the same static values.
Worked example: CSV feeder for login credentials
Assume a file users.csv with header username,password and a few rows:
username,password alice,secret1 bob,secret2 charlie,secret3
The following Scala snippet shows how to load the file, make it circular (so it repeats when the end is reached), and feed it before the request chain:
import io.gatling.core.Predef._
import io.gatling.http.Predef._
import scala.concurrent.duration._
class LoginSimulation extends Simulation {
val httpProtocol = http
.baseUrl("https://example.com")
.acceptHeader("text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8")
// 1. Load CSV and make it circular
val csvFeeder = csv("users.csv").circular
val scn = scenario("Login with unique credentials")
// 2. Attach the feeder – one record per iteration
.feed(csvFeeder)
.exec(
http("Login request")
.post("/login")
.formParam("username", "${username}")
.formParam("password", "${password}")
.check(status.is(200))
)
.pause(5)
setUp(
scn.inject(constantUsersPerSec(10) during (30.seconds))
).protocols(httpProtocol)
}
Each time the exec block runs, Gatling takes the next record from csvFeeder, assigns the values to the session attributes username and password, and those attributes are then referenced in the request body via the ${} syntax.
How the feeder works under the hood
The csv method reads the entire file into an immutable IndexedSeq[Record] held in the JVM heap. When .circular is applied, Gatling wraps the sequence so that after the last record it returns to the first. The feed operation pulls the next element from this sequence for each user iteration, guaranteeing exactly one consumption per exec step where the feeder is placed.
Limits and memory considerations
- In‑memory loading: The whole CSV resides in RAM. A file with millions of rows or wide columns can trigger
OutOfMemoryError. - Alternative approaches: For very large datasets, implement a custom feeder that reads line‑by‑line from a
BufferedReaderor use a JDBC feeder that queries the database per iteration. - Feeder exhaustion: If you omit
.circularand the number of iterations exceeds the record count, Gatling throwsIllegalArgumentException: Feeder is empty.
Common configuration mistakes
- Placing
.feed(csvFeeder)inside anexecblock (e.g.,.exec(feed(csvFeeder))) causes the feeder to be consulted multiple times per request, leading to skipped records or premature exhaustion. - Sharing a single feeder instance across two unrelated scenarios without realizing that each scenario will consume from the same sequence, resulting in uneven data distribution.
- Modifying the underlying CSV file while the test is running; feeders are immutable after startup, so external changes are not reflected and can cause confusion.
- Using relative paths that work in the IDE but not when the simulation is launched from a different working directory; always provide an absolute path or locate the file via
getClass.getResource.
Verification steps
- Run a short test with a tiny CSV (two rows) and log the session values:
.exec(session => { println(session("username")); session }). Confirm that each iteration prints the expected username. - Watch the Gatling console for warnings like
Feeder is empty; their absence indicates the feeder supplied data for the whole run. - Monitor heap usage with
jstat -gc <pid>or VisualVM while the test starts; a steady rise proportional to the CSV size confirms the in‑memory loading behavior. - If you implement a custom feeder, add a print statement in its
hasNextornextmethod to verify it is called once per user iteration.
Takeaway
For most load‑testing scenarios a CSV feeder with .circular provides a simple, reliable way to give each virtual user unique data. Keep the feeder file modest in size, place .feed directly on the scenario chain, and verify the feed with a quick log‑based sanity check before scaling up to the full test load.
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.