Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/gatling/gatling.io-doc/llms.txt

Use this file to discover all available pages before exploring further.

A Gatling scenario is a blueprint that describes the sequence of actions a virtual user will perform during a load test. Every step — from sending HTTP requests to pausing between actions, branching on conditions, looping over lists, or gracefully handling errors — is expressed through the scenario DSL. Scenarios are composable: you can extract chains into reusable constants, combine them with loops and conditionals, and ultimately attach them to an injection profile in setUp.

Bootstrapping

Use scenario() to create a new scenario builder. You may use any characters in the name except tab characters (\t).
ScenarioBuilder scn = scenario("Scenario");

exec — Executing Actions

exec is the primary method for attaching actions to a scenario. An action is usually a protocol request (HTTP, WebSocket, JMS, MQTT, etc.), but it can also be a function that reads or modifies the session.
// attached to a scenario
scenario("Scenario")
  .exec(http("Home").get("https://gatling.io"));

// directly created and stored in a reference
ChainBuilder chain = exec(http("Home").get("https://gatling.io"));

// executed sequentially
exec(
  http("Home").get("https://gatling.io"),
  http("Enterprise").get("https://gatling.io/enterprise")
);

// chained
exec(http("Home").get("https://gatling.io"))
  .exec(http("Enterprise").get("https://gatling.io/enterprise"));

Session Functions in exec

You can pass a function to exec to read or update the Session. This is primarily used for debugging or for programmatic session manipulation.
Functions passed to exec run on Gatling’s shared threads. Never perform long blocking operations (remote calls, file I/O, etc.) inside them — doing so will stall the engine.
Gatling SDK components are definitions, not actions. Creating an HTTP request object inside an exec function has no effect — it must be chained into the scenario, not instantiated inside a function body.
exec(session -> {
  // for debugging only — sysout is slow under load
  System.out.println(session);
  return session;
});

exec(session ->
  session.set("foo", "bar")
);

Pauses

pause — Think Time

Use pause to model the time a user spends reading a page before their next interaction. It supports fixed durations, uniform random ranges, EL strings, and functions.
// fixed pauses
pause(10);                                   // 10 seconds
pause(Duration.ofMillis(100));
pause("#{pause}");                           // Gatling EL
pause(session -> Duration.ofMillis(100));

// uniform random pauses
pause(10, 20);
pause(Duration.ofMillis(100), Duration.ofMillis(200));
pause("#{min}", "#{max}");
pause(session -> Duration.ofMillis(100), session -> Duration.ofMillis(200));

pace — Iteration Rate Control

pace is a special pause type that adjusts its wait time based on how long the previous iteration took, allowing you to target a specific iterations-per-second rate regardless of processing time.
forever().on(
  pace(5)
    .exec(
      // runs every 5 seconds, regardless of inner pause durations
      pause(1, 4)
    )
);

rendezVous — Synchronization Point

Use rendezVous to hold virtual users at a checkpoint until a specified number of users have arrived, then release them all simultaneously.
rendezVous(100);

Loop Statements

When using the optional counterName parameter to name a loop counter, treat that session attribute as read-only. Writing to it will break Gatling’s internal loop tracking logic.

repeat

Repeat the loop body a fixed number of times (int, EL string, or function).

foreach

Iterate over every element in a sequence, binding each element to a session key.

during

Loop for a fixed duration; optionally exit early between elements (exitASAP).

asLongAs

Loop while a boolean condition holds; condition evaluated before each iteration.

doWhile

Like asLongAs but the condition is evaluated after each iteration.

asLongAsDuring

Loop while a condition holds AND the duration has not elapsed; condition checked before each iteration.

doWhileDuring

Like asLongAsDuring but the condition is evaluated after each iteration.

forever

Loop indefinitely until an error or an explicit exit action terminates the user.
// repeat N times
repeat(5).on(http("name").get("/"));
repeat("#{times}").on(http("name").get("/"));
repeat(5, "counter").on(http("name").get("/?counter=#{counter}"));

// foreach over a list
foreach(List.of("elt1", "elt2"), "elt").on(
  http("name").get("/?elt=#{elt}")
);

// loop for a duration
during(Duration.ofMinutes(10)).on(http("name").get("/"));
during(5, "counter", false).on(http("name").get("/?counter=#{counter}"));

// loop while condition holds (condition before each iteration)
asLongAs("#{condition}").on(http("name").get("/"));
asLongAs(session -> session.getBoolean("condition")).on(http("name").get("/"));

// loop while condition holds (condition after each iteration)
doWhile("#{condition}").on(http("name").get("/"));

// loop while condition holds AND duration not elapsed
asLongAsDuring("#{condition}", Duration.ofMinutes(5)).on(http("name").get("/"));

// same but condition evaluated after each iteration
doWhileDuring("#{condition}", Duration.ofMinutes(5)).on(http("name").get("/"));

// loop forever
forever().on(http("name").get("/"));

Conditional Statements

Gatling supports if-style and switch-style branching based on session values or arbitrary functions.
// if condition
doIf("#{condition}").then(http("name").get("/"));
doIf(session -> session.getBoolean("condition")).then(http("name").get("/"));

// if / else
doIfOrElse("#{condition}").then(
  http("name").get("/")
).orElse(
  http("else").get("/")
);

// equality check
doIfEquals("#{actual}", "expectedValue").then(http("name").get("/"));

// equality check with else branch
doIfEqualsOrElse("#{actual}", "expectedValue")
  .then(http("name").get("/"))
  .orElse(http("else").get("/"));

// switch
doSwitch("#{myKey}").on(
  onCase("foo").then(http("name1").get("/foo")),
  onCase("bar").then(http("name2").get("/bar"))
);

// switch with fallback
doSwitchOrElse("#{myKey}").on(
  onCase("foo").then(http("name1").get("/foo")),
  onCase("bar").then(http("name2").get("/bar"))
).orElse(http("other").get("/other"));

// probabilistic switch (Markov chain)
randomSwitch().on(
  percent(60.0).then(http("name1").get("/foo")),
  percent(40.0).then(http("name2").get("/bar"))
);

// probabilistic switch with fallback
randomSwitchOrElse().on(
  percent(60.0).then(http("name1").get("/foo"))
).orElse(http("other").get("/other"));

// uniform random switch
uniformRandomSwitch().on(
  http("name1").get("/foo"),
  http("name2").get("/bar")
);

// round-robin switch
roundRobinSwitch().on(
  http("name1").get("/foo"),
  http("name2").get("/bar")
);
In randomSwitch, percentages must sum to ≤ 100. Users who fall outside the defined ranges simply continue past the switch. Format as 60 for 60%, 33.3 for 33.3%, etc.

Error Handling

tryMax — Retry on Failure

Any technical error (timeout, failed check) within the wrapped chain causes the virtual user to restart the block from the beginning, up to a maximum number of attempts. All failing requests are still recorded.
tryMax(5).on(
  http("name").get("/")
);

// with a named counter
tryMax(5, "counter").on(
  http("name").get("/")
);

exitBlockOnFail — Abort on Failure

Like tryMax but without any retry — the user exits the block immediately on the first failure.
exitBlockOnFail().on(
  http("name").get("/")
);

exitHere and exitHereIf

Make the virtual user exit the scenario at a specific point, either unconditionally or based on a condition.
exitHere();

exitHereIf("#{myBoolean}");
exitHereIf(session -> true);

// exit if a previous action failed
exitHereIfFailed();

stopLoadGenerator and crashLoadGenerator

Force an abrupt shutdown of the entire load generator with a descriptive message. The crash variant exits with a non-zero failure code.
stopLoadGenerator("#{someErrorMessage}");
stopLoadGenerator(session -> "someErrorMessage");

crashLoadGenerator("#{someErrorMessage}");
crashLoadGenerator(session -> "someErrorMessage");

// conditional variants
stopLoadGeneratorIf("#{someErrorMessage}", "#{condition}");
crashLoadGeneratorIf("#{someErrorMessage}", "#{condition}");

Group — Logical Grouping

Use group to cluster related requests together for reporting purposes. Groups appear as aggregated metrics in the Gatling report. Groups can be nested.
Group names must not contain commas.
group("foo").on(
  http("request1").get("/"),
  pause(1),
  http("request2").get("/")
);

Dummy Actions

A dummy action simulates a call to a remote system — with a configurable response time and success/failure outcome — without actually making a network request. This is useful when you cannot connect to the real backend but still need business process metrics.
// successful dummy action with a fixed 1000ms response time
dummy("Dummy Request Name", 1000);

// failed dummy with a response time from session
dummy("Dummy Request Name", "#{responseTime}").withSuccess(false);

// random response time using a Gatling EL function
dummy("Dummy Request Name", "#{randomInt(5,10)}");

// dummy that also updates the session
dummy("Dummy Request Name", 1000)
  .withSessionUpdate(session -> session.set("foo", "bar"));

Build docs developers (and LLMs) love