In a Gatling simulation, what does attaching noShard to an injected population change, and when does it change nothing at all?
answer
- opts out of Enterprise load sharding
- per population, not per simulation
- every generator runs the profile in full
- the bootstrap token population needs it
- no-op outside Gatling Enterprise
basics
~10 sIt opts one population out of Gatling Enterprise's load sharding, so every load generator applies that population's injection and throttling profiles as declared. Outside Gatling Enterprise it does nothing, because nothing shards.
solid answer
~40 sBy default Gatling Enterprise spreads a population's injection profile across all the load generators in a run, so `atOnceUsers(1)` means one user somewhere in the fleet. `noShard` switches that off for the population it is attached to: every generator then applies that population's injection and throttling profiles in full. The classic reason is a bootstrap population that logs in once to fetch a token; sharded, only one node would run it and the others would start untokenised. It is per population, not per simulation, so a population attached as a child of an exempt parent still shards unless it calls `noShard` too. Java, Kotlin and JavaScript write `.noShard()`; Scala writes `.noShard`. Outside Gatling Enterprise it is documented as a no-op.
code
java · 26 linesimport static io.gatling.javaapi.core.CoreDsl.*;
import static io.gatling.javaapi.http.HttpDsl.*;
import io.gatling.javaapi.core.ScenarioBuilder;
import io.gatling.javaapi.core.Simulation;
import java.time.Duration;
public class BootstrapThenLoadSimulation extends Simulation {
private final ScenarioBuilder bootstrap =
scenario("fetch token").exec(http("token").post("/oauth/token"));
private final ScenarioBuilder main =
scenario("browse").exec(http("catalog").get("/catalog"));
{
setUp(
bootstrap
.injectOpen(atOnceUsers(1))
.noShard()
.andThen(
main.injectOpen(
constantUsersPerSec(50).during(Duration.ofMinutes(5)))))
.protocols(http.baseUrl("https://example.com"));
}
}go deeper
Recall that noShard attaches to an injected population and only matters on Gatling Enterprise. Know the two spellings: noShard() in Java, Kotlin and JavaScript, and noShard in Scala.
Be ready to explain the default it turns off, namely Enterprise spreading a population's injection and throttling profile across generators, and that the opt-out covers only the population it is written on.
Be ready to give the operational case for it: a one-user setup population fetching shared credentials, which if sharded leaves every other generator starting its real work uninitialised.
Own the call on whether a run should depend on per-generator bootstrap at all, given that noShard is inert on Community and the failure it prevents cannot be reproduced until the fleet exceeds one machine.
## The default `noShard` turns off When Gatling Enterprise runs a simulation across several load generators, it **shards the injection profile**: the users a population declares are divided among the generators so that the fleet, taken together, applies the profile you wrote. Declare `atOnceUsers(1)` and exactly one user starts, somewhere in the fleet. Declare `constantUsersPerSec(400)` across four generators and each contributes roughly a quarter of the arrival rate. That is the right default almost all of the time, and it is what makes "add another generator" mean "more capacity" rather than "more load". ## What `noShard` does `noShard` marks **one population** as exempt. Gatling's documentation states the effect directly: with `noShard`, all the nodes use the **injection and throttling profiles as defined in the Simulation**. So the exempt population is not divided at all — every generator applies its steps in full. Two details matter and are easy to get wrong: - **It is per population, not per simulation.** The flag lives on the `PopulationBuilder` that `injectOpen`, `injectClosed` or Scala's `inject` returns. Populations attached as children of an exempt parent are **still sharded** unless they call `noShard` themselves — Gatling's own documentation sample shows precisely that shape, an exempt parent with a sharded child. - **It covers throttling too**, not just the injection steps. A per-population throttle profile on an exempt population is applied whole on every generator. ## The reason it exists The canonical case in Gatling's documentation is a **bootstrap population**: a first scenario run by a single virtual user that logs in and fetches an auth token for the real scenario to use. Sharded, that single user lands on exactly one generator, and the remaining generators start their real work with no token — the run fails for a reason that has nothing to do with the system under test. Marking the bootstrap population `noShard` makes every generator do its own bootstrap, which is what you wanted. ## Spelling, by SDK The step names in Gatling's DSL are the same across the SDKs, but this one differs in punctuation because Scala allows parameterless methods without parentheses: | SDK | how it is written | |---|---| | Java | `scn.injectOpen(atOnceUsers(1)).noShard()` | | Kotlin | `scn.injectOpen(atOnceUsers(1)).noShard()` | | JavaScript / TypeScript | `scn.injectOpen(atOnceUsers(1)).noShard()` | | Scala | `scn.inject(atOnceUsers(1)).noShard` | A question or a snippet that shows `.noShard` without parentheses as "the Gatling syntax" is wrong in three of the four, and one that shows `.noShard()` as universal is wrong in Scala. ## When it changes nothing at all Outside Gatling Enterprise, `noShard` is a **documented no-op**. The Java API's own contract says so: *"Only effective when the test is running with Gatling Enterprise, noop otherwise."* And it has to be, because the Community Edition never shards anything in the first place — there is no fleet, no controller and no division to opt out of. A population is created with sharding enabled and `noShard` merely flips that flag to false; nothing in the Community Edition's run path ever reads it. The practical consequence is a **silent behavioural difference between environments**. The same simulation, unchanged: 1. On a developer machine — `noShard` present or absent, identical behaviour, identical report. 2. On Gatling Enterprise with one generator — still identical, because a fleet of one is not divided in any observable way. 3. On Gatling Enterprise with several generators — now the flag decides whether a population runs once across the fleet or once per generator. So the bug `noShard` prevents cannot be reproduced locally and does not appear until the fleet grows past one machine. If your simulation depends on a per-generator bootstrap, that dependency is worth a comment in the code, because no local run will ever exercise it. ## The word next door Feeders have a `shard` option too, and the two are opposites in polarity. A **population** is sharded by default and `noShard` opts it out; a **feeder** is not sharded by default and `.shard()` opts it in. Both are inert outside Gatling Enterprise. Conflating them is the most common mistake in this corner of the DSL: writing `noShard` on a population and expecting the feeder to stop slicing, or writing `.shard()` on a feeder and expecting the injection profile to change.
- Which profiles does noShard exempt from sharding, only the injection steps?Both. Gatling's documentation states that with `noShard` all the nodes use the injection **and throttling** profiles as defined in the simulation, so a per-population throttle is applied whole on every load generator rather than divided among them.
- If a population declared with noShard has children attached to it, do the children inherit the opt-out?No. `noShard` sets a flag on the population it is called on, and nothing propagates it downwards. Gatling's own documentation sample shows an exempt parent whose child load is still sharded; a child needs its own `noShard` call to be exempt.
saying these in an interview costs you the question
- Thinking noShard changes anything in Gatling's Community Edition
- Believing noShard applies to the whole simulation rather than one population
- Confusing noShard with the feeder shard option, which is opt-in
- Assuming noShard also alters the report or the assertion chain