Your Gatling simulation needs more load than one injector can produce, so what do you take on yourself by hand-running the Community Edition on several machines, and what would make you stop and change approach?
answer
- four runs, not one run
- launch, divide, separate, collect, aggregate
- no supported combined report exists
- the verdict rule is yours to write
basics
~10 sYou take on launching, dividing the profile, separating the data, collecting artefacts and aggregating verdicts, everything a distribution product would do. Change approach once that homemade aggregation starts deciding whether releases ship.
solid answer
~40 sGatling's Community Edition gives you one injector and one report, so running four is four unrelated runs and everything between them is yours. Concretely: launching and stopping the machines together, dividing the declared profile so the fleet applies the total you intended, keeping their input data apart, collecting four results directories that share no run identifier, and turning four exit codes into one pipeline verdict. What you cannot build is the combined report, because the only run-wide input is a binary log Gatling explicitly documents as not an integration surface. The point to change approach is when a decision rests on the number you cannot produce: if release gating or an externally reported figure needs one run-wide result, homemade aggregation is a correctness risk rather than a saving.
go deeper
Recall that several Gatling Community Edition machines are several independent runs, and that nobody merges them for you.
Be ready to list what sits between the machines and is therefore yours: launching, dividing the profile, separating the data, collecting artefacts, and deciding the verdict.
Be ready to describe the operational shape you would actually run, and to be honest about which parts of it are approximations rather than the measurement a coordinated run would have produced.
Own the threshold. Say plainly which decisions may rest on a hand-aggregated result and which may not, and name what moves the line: release gating, an externally reported figure, or a fleet that keeps growing.
## Start from what the edition actually gives you Gatling's Community Edition gives you **one injector and one report**. It has no controller, no agent topology and no result aggregation, and Gatling's FAQ says so directly: multiple load generators are an Enterprise Edition feature and the Community Edition is not supported for distributed testing. So "run it on four machines" is not a feature you switch on. It is four independent runs, and everything **between** those runs is work you have just volunteered for. ## The five things that become yours 1. **Launching and stopping together.** Four processes have to start close enough in time for their steady-state windows to overlap, and you have to notice when one never started — a fleet that silently ran three of four machines applies three-quarters of the load and reports nothing unusual. 2. **Dividing the profile.** Each JVM runs `setUp(...)` exactly as written, so a rate declared once is applied once **per machine**. The intended fleet total has to be divided by hand, in the simulation, from a value you pass in. 3. **Keeping the input data apart.** The feeder `.shard()` option will not do this for you off Gatling Enterprise; it is a documented no-op there. Separate files, or a slice you compute yourself, or data derived per virtual user. 4. **Collecting and correlating artefacts.** Each machine writes a results directory named from the simulation id plus its own millisecond start timestamp — no host, no generator index, no random suffix — so the four names differ by luck rather than by design, and nothing in them records that they belong to one logical run. Label them as you gather them: two nodes that reached their load step in the same millisecond produce the same directory name, and one node's artefacts then land on top of another's. There is no run-wide id to lean on: `deploymentInfo.runId` is populated only on Gatling Enterprise. 5. **Deciding the verdict.** Each machine evaluates the whole assertion chain over its own traffic and exits on that answer alone, with status 2 when its own assertions failed. Four exit codes arrive; the rule that turns them into one is yours to write. ## The one thing you cannot build A **combined report**. The only run-wide input would be the four `simulation.log` files, and that door is closed by design: the format is an undocumented binary that Gatling calls an implementation detail subject to change without notice, whose FAQ entry answers *"Can I parse the simulation.log file myself?"* with a one-word *"No."* Its header pins the Gatling version, and the reader rejects a file written by a different one — so even a working parser is one routine upgrade away from breaking. Anything you build there is unsupported tooling that your team now owns, on a schedule set by someone else's release notes. ## How to decide The honest test is not "how much load do we need" — it is **what decisions will rest on the number you cannot produce**. | the run's job | hand-run fan-out | |---|---| | a one-off capacity investigation you will read and discuss | fine; four reports is four data points | | a repeated comparison against a previous run | workable, if the fleet shape is held identical | | an automated gate that blocks a release | the weak point; the aggregation deciding it is homemade | | an externally reported or contractual figure | do not; there is no run-wide figure to report | Two further signals that it is time to change approach: - **The fleet keeps growing.** Four machines launched by a script is a chore. Twelve is a product you did not mean to write, and the failure modes — one node lagging, one node never starting — stop being obvious. - **The aggregation starts acquiring rules.** The moment someone proposes tolerating one failing node, or averaging figures across reports, the homemade layer is making judgement calls that nobody reviewed. ## The defensible middle If you do stay, the pass rule that survives scrutiny is the strict one: **every injector must pass its own assertion chain, and every exit code must be zero.** It needs no merging at all, and it is honest about what was measured — four independent samples of the same profile, each judged on its own statistics. It is not the same thing as one verdict over the whole run, and the difference should be written down rather than glossed over. It is tempting to call that rule *stricter* than a run-wide one, and for the assertions people normally gate on it is — but not for all of them, and the exceptions are the ones that bite: | assertion metric | all-four-must-pass, against one run-wide rule | |---|---| | `responseTime` min/max/mean/`percentileN` | at least as strict; the pooled figure cannot exceed the worst node's | | `failedRequests.percent` and its siblings | at least as strict; a pooled percentage is a weighted average of the four | | `failedRequests.count` and its siblings, upper-bounded | **looser**; counts add up — four nodes at 99 failures each pass `.count.lt(100)`, the pooled 396 does not | | `requestsPerSec` or `responseTime.stdDev`, upper-bounded | **looser**; the rate adds up across the fleet, and pooled spread grows when the per-node means differ | So the defensible claim is "at least as strict for the percentile, mean and percentage assertions", not "strictly stricter". If the chain carries an upper-bounded `.count` or rate assertion, per-node all-pass is the **weaker** rule there, and that belongs in the same note as everything else. What does not survive scrutiny is inventing a fleet-wide figure by arithmetic on four reports. Gatling produces no such figure, and producing one yourself replaces a measurement with an estimate at exactly the point where somebody is about to trust it.
- Why is building your own merged Gatling report from the injectors' output not a supportable plan?Because the input is off-limits. `simulation.log` is a binary implementation detail whose format Gatling documents as undocumented and subject to change, and whose header the reader rejects when the Gatling version differs. Anything built on it is unsupported tooling that a routine upgrade can break.
- If you fan out to four Gatling injectors, what is a defensible way to reach a single pass or fail?Require every injector to pass its own assertion chain and treat any non-zero exit as a failed run. It needs no merging, and it is honest about what was measured: four independent samples of one profile, each judged on its own statistics. Be exact about its strength, though. It is at least as strict as a run-wide rule only for metrics whose pooled value is bounded by the per-node ones: `responseTime` min, max, mean and percentiles, and the `.percent` forms of the request counts. For the metrics that add up across the fleet under an upper bound it is looser — four injectors at 99 failures each all pass `failedRequests.count.lt(100)` while the pooled 396 would fail it, and `requestsPerSec` and `responseTime.stdDev` behave the same way.
- What has to change in the simulation itself before it can be hand-run on four machines?The declared profile and the data. Divide the injection rates or user counts so the fleet applies the intended total, since every machine runs `setUp` as written, and make sure the four are not drawing the same records; the feeder `.shard()` option will not separate them outside Gatling Enterprise.
saying these in an interview costs you the question
- Treating hand-run fan-out as equivalent to a coordinated distributed run
- Planning to parse simulation.log to build a combined report
- Gating a release on one injector's assertion verdict alone
- Forgetting to divide the declared profile by the machine count