In a Gatling scenario, what does rendezVous(100) do to the virtual users that reach it, and what happens when a user reaches it a second time?
answer
- a barrier in the middle of a scenario
- holds users until the count arrives
- releases all of them at once
- fires once, then passes everyone through
basics
~20 srendezVous(100) holds each arriving virtual user until a hundred are waiting, then releases all of them together. It then becomes a permanent pass-through, so every later arrival, including a user's second visit, goes straight through without waiting.
solid answer
~50 s`rendezVous(n)` is a barrier. It buffers the sessions of virtual users that reach it and, the moment the buffer holds `n` of them, releases all `n` at once — which is how you produce a deliberately simultaneous burst rather than the spread-out arrivals a scenario normally makes. The part people miss is that it fires **exactly once**: after the release the step turns into a pass-through for the rest of the run, so a `rendezVous` inside a loop does not re-synchronise the population on each lap. The other risk is a barrier that can never fill. If fewer than `n` users ever reach it — a population smaller than `n`, users lost to failures on the way, or a count drawn from a different population — the waiting ones are never released and nothing fails or logs, so give any run that uses it a maximum duration.
code
java · 4 linesScenarioBuilder scn = scenario("Flash sale")
.exec(http("Product").get("/product/42"))
.rendezVous(100)
.exec(http("Buy").post("/product/42/buy"));go deeper
Be ready to say what a barrier step is for: releasing a fixed number of virtual users at the same instant.
Be ready to explain that it buffers sessions until the count is reached and then turns into a pass-through for the rest of the run.
Be ready to diagnose a run that stops making progress at a barrier, and to say why nothing was logged when it happened.
Be ready to argue when a coordinated burst is worth the fragility of a barrier at all, versus expressing the demand in how load arrives.
`rendezVous(n)` is Gatling's barrier: a step that holds arriving virtual users until `n` of them are standing there, then lets all `n` go at the same instant. It is the tool for producing a deliberate simultaneous burst — everyone submits the order in the same moment — rather than the spread-out arrivals a normal scenario produces. ## What the step does, precisely The action keeps a queue of the sessions that have reached it. Each arrival is appended. When the queue's size reaches `n`, every buffered session is released at once, the queue is cleared, and **the action changes behaviour permanently: from then on it is a pass-through.** That last sentence is the whole question. `rendezVous` is a *one-shot* barrier, not a recurring one: * The first `n` users wait and are released together. * User `n + 1` and everyone after arrives at a pass-through and never waits. * A user that loops back to the same `rendezVous` on its second lap also arrives at a pass-through. So `rendezVous` inside a `repeat` or `forever` body does **not** re-synchronise the population on every lap. It synchronises exactly once, on the first release, and is inert thereafter. ## The failure mode: fewer users than the barrier asks for Because the barrier only fires on reaching its exact count, a run that never gets `n` users to that point leaves the ones that did arrive buffered indefinitely. They are not failed, not logged, and not counted as errors — they simply never continue, so the scenario never finishes for them and the run does not end on its own. It takes something else to stop it, such as a declared maximum duration on `setUp`. Three ordinary situations produce that: 1. **The population is smaller than the barrier.** `rendezVous(100)` in a scenario injected with 40 users can never be satisfied. 2. **Users are lost before the barrier.** Failures, an `exitHereIfFailed`, or a conditional branch that skips the barrier can all mean that fewer than `n` users reach the step even though more than `n` started. An exhausted feeder is *not* one of these, and it is worth knowing why: when the feeder has no record left, `FeedActor` never forwards the session at all — it sends the controller a `StopLoadGenerator` command carrying a crash reason ("Feeder <name> crashed: feeder is now empty."), which cancels any `maxDuration` timer, stops the stats engine with `crash=true` and tears the whole run down. A feeder running dry ends the run loudly rather than hanging it quietly. 3. **The barrier counts only its own population.** Each injected population builds its own barrier instance, so users of a different scenario never count towards it. Two populations of 60 users each do not add up to 100 at "the same" `rendezVous`. The practical rule that follows: pick `n` from the number of users you are confident will *reach that step*, not from the number you inject, and always give a run that uses `rendezVous` a maximum duration so a miscount cannot hang the job. ## What it is and is not | | `rendezVous(n)` | |---|---| | scope | the virtual users of one built population | | fires | once, on the first time `n` are waiting | | after that | a permanent pass-through | | effect of the run's pause type | none — the barrier is built without consulting it | | users while waiting | still live: they hold a session and are still part of the run | | when `n` is never reached | they wait indefinitely; nothing fails or logs | Note the fourth row. `disablePauses()` on `setUp` strips every `pause` out of a run but leaves every `rendezVous` in place, because the pause type is consulted only when building a `pause`. "Turn off all the waiting" is not something a single switch does. ## Using it well * Put the barrier immediately before the step you want synchronised, and nothing else between them, so that the released users are as close to simultaneous as the load generator can make them. * Size `n` well under the number injected when any part of the preceding chain can fail, and prefer a barrier you are certain will fill. * Do not use it to build a sustained rate. A barrier produces exactly one coordinated burst; declaring how load arrives over time is the job of the injection profile, not of a waiting step. * Remember it is per population. If you need two scenarios to hit the same moment, a single scenario with a barrier is a far more reliable construction than two barriers in two populations. ## The argument type `rendezVous` takes a plain `int` — the number of virtual users that must reach the point. There is no expression form, no session-derived count and no range: the number is fixed when the simulation is built, which is exactly why a mismatch between it and the number of users that actually arrive is a design-time mistake rather than something the run can adapt to.
- Does rendezVous(100) count virtual users across every population in the setUp?No. Each injected population builds its own barrier instance, so only the users of that population count towards its total. Two populations of sixty users each will not combine into a hundred at what looks like the same step in a shared chain.
- What does a virtual user waiting at a rendezVous cost the run?It holds its session and stays part of the run, but it issues no requests and is not recorded anywhere, so it is invisible in the statistics while it waits. In a closed model those users still count against the concurrent total even though they are doing nothing.
- How would you make a barrier fire repeatedly, once per loop iteration?You cannot, with this step. The action becomes a pass-through after its first release, so there is no per-iteration barrier in the DSL. If a repeated burst is the requirement, express it in how load arrives rather than by trying to re-synchronise users mid-scenario.
It is a ferry that will not sail until a hundred passengers are aboard — and then, having sailed once, leaves the gangway open for good, so nobody who turns up later waits for anything.
saying these in an interview costs you the question
- Expecting the barrier to re-arm on every loop iteration.
- Sizing the count from users injected, not users arriving.
- Assuming a barrier that cannot fill fails the run.
- Thinking disablePauses also removes a rendezVous.