skip to content

In Gatling, which four record-consumption strategies can you set on a feeder, and which one applies if you set none?

level: juniorimportance: must knowfreq 68%

answer

  1. exactly four, no fifth option
  2. two consume the stock, two reuse it
  3. the default needs no method call
  4. queue, random, shuffle, circular

basics

~20 s

Gatling feeders take exactly four strategies: queue, random, shuffle and circular. Queue is the default. Queue and shuffle hand out each record once and stop the run when the stock empties; random and circular reuse records and never run out.

solid answer

~40 s

A Gatling feeder carries one of exactly four consumption strategies, set on the builder: `queue()`, `random()`, `shuffle()` or `circular()` in Java, Kotlin, JavaScript and TypeScript, and the same names without parentheses in Scala, as in `csv("data.csv").circular`. `queue` is the default and needs no call: records go out in the source's own order, each exactly once. `shuffle` is the same contract with the order permuted once at start-up. Both are consuming, so when the last record has gone the next virtual user to reach the `feed` step stops the whole run. `random` draws a record independently on every call and `circular` walks the source and wraps at the end — both can hand one record to several users, and neither can ever run out.

code

java · 4 lines
java
FeederBuilder<String> credentials = csv("credentials.csv");
FeederBuilder<String> searchTerms = csv("search-terms.csv").random();
FeederBuilder<String> productIds = csv("products.csv").circular();
FeederBuilder<String> coupons = csv("coupons.csv").shuffle();

go deeper

for a junior

Be ready to name all four strategies and say which one you get for free. Knowing that queue is the default is the single most useful fact here.

for a middle

Explain the two axes the four strategies sit on: order versus source order, and consuming versus reusing. Say when the start-up permutation of shuffle happens.

for a senior

Show that you pick the strategy from what the data represents rather than from habit, and that you know a consuming strategy turns the file into a run-duration budget.

for a principal

Own the rule for a whole suite: which data classes get a consuming strategy, who keeps the stock large enough, and what you do when four fixed strategies are not enough.

## What a strategy is, and where it lives A **feeder** in Gatling is a stock of records that virtual users draw from when they reach a `feed` step. Every virtual user in the simulation feeds from the *same* stock: the feeder is built once, before any user starts, and shared for the whole run. The **strategy** is the rule that decides which record the next caller gets and whether a record that has already gone out can come back. Gatling defines exactly four strategies, and they are set by calling a method on the feeder builder returned by `csv(...)`, `jsonFile(...)`, `arrayFeeder(...)` and friends: | strategy | order records go out in | can two users get the same record? | what happens at end of data | |---|---|---|---| | `queue` | the source's own order | no | the run is stopped | | `shuffle` | one random permutation | no | the run is stopped | | `random` | an independent draw each time | yes | never reached | | `circular` | the source's own order, wrapping | yes | never reached | `queue` is the default. `csv("data.csv")` and `csv("data.csv").queue()` build the same feeder, which is why the calls are usually absent from real simulations and why the default is the behaviour most teams actually run. ## The two that consume the stock - **`queue`** hands out record 1, then record 2, then record 3, in the order the source declares them. No record is ever handed out twice. - **`shuffle`** is the same contract with the order scrambled. The important detail is *when* the scramble happens: Gatling permutes the whole record set **once, while building the feeder at start-up**, and then walks that fixed permutation. It does not re-roll per virtual user. Both are finite. Each `feed` step execution removes one record from what is left, and when the last one has gone the next caller finds the stock empty, at which point Gatling stops the load generator and the run ends as a crash. That is the correct behaviour for data that carries an identity — a login, a one-shot coupon code, an account number — because the alternative would be two virtual users acting as the same principal at the same time. ## The two that never run out - **`random`** draws a record independently on every call, from the whole stock, with replacement. Two users can get the same record; over a short run some records may be drawn several times and others never at all. (That is the behaviour of a feeder held in memory, which is every source small enough not to be streamed. A file large enough to be streamed instead shuffles a rolling block of records and walks it in order, so there a record cannot repeat until the block refills.) - **`circular`** keeps a reading index over the source in its declared order and moves it back to the first record when it passes the last one. Over a long run every record is used very nearly the same number of times, and the order is completely predictable. Neither can empty, so neither can end a run. They suit data with no uniqueness constraint: search terms, product identifiers to browse, postcodes to look up. ## How the four are spelled across the SDKs The names are identical in every SDK; only the call syntax differs. 1. **Java, Kotlin, JavaScript and TypeScript** go through the Java API's `FeederBuilder` interface, where the four are ordinary methods: `csv("data.csv").circular()`. 2. **Scala** declares them as parameterless methods, so a Scala simulation writes `csv("data.csv").circular` with no parentheses. They are not exclusive to file-backed feeders either. An in-memory feeder built from an array or a list takes the same four, because the strategy is a property of the builder rather than of the source. ## Picking one The question that decides it is whether the target must see each record at most once. If yes, you are in `queue`/`shuffle` territory and the size of the file becomes a budget the run has to stay inside. If no, `random` or `circular` removes the whole class of end-of-data failures and lets a small file drive an arbitrarily long run. `shuffle` over `queue` buys you protection against accidental correlation with the file's order; `circular` over `random` buys you an even sweep instead of a lumpy one. ## Where the choice actually bites Two consequences follow from the table above and they are what interviews probe. - **A consuming strategy turns the source into a budget.** The number of records has to be at least the number of times a `feed` step runs over the whole simulation, and that number is driven by the injection profile rather than by anything visible in the scenario. Under-size it and the run ends early with nothing to show. - **A reusing strategy trades that budget for duplication.** `random` and `circular` cannot fail this way, but they hand one record to several virtual users concurrently. On data the target treats as an identity, that duplication is not a harmless approximation: it changes what the run measures. There is no fifth option and the four take no arguments, so the strategy is the whole of the decision. If neither pair fits, the way out is a feeder of your own — Gatling treats a feeder as an iterator of string-keyed records, so any object of that shape can be handed to `feed`.

  • Does `shuffle` pick a fresh random order for each virtual user?
    No. Gatling permutes the whole record set once, when the feeder is built at start-up, then walks that fixed permutation like a queue. Every virtual user draws from the same single ordering, no record is served twice, and the stock still empties after exactly as many draws as `queue` would allow.
  • Do these strategies apply only to CSV files?
    No. The strategy is a property of the feeder builder, not of the source, so an in-memory feeder built from an array or a list takes the same four. Only options tied to files, such as decompression, are restricted to file-backed feeders.

A consuming feeder is a stack of printed cloakroom tickets: hand out the last one and the queue stops moving. A circular feeder is a carousel — the same seats come round again, and it never empties.

saying these in an interview costs you the question

  • Assuming a feeder wraps back to the first record automatically
  • Believing shuffle re-randomises the order for every virtual user
  • Treating random and circular as interchangeable; only circular keeps source order
  • Writing the Scala strategy calls with parentheses like the Java ones