Gatling

Gatling strengths and when teams choose it for more complex, larger-scale performance scenarios.

Updated:

Contents

Gatling supports load scenarios maintained as code: reviewing changes, preserving history, and repeating experiments with known configuration. It models operation flows and measures outcomes. This article uses the Java SDK for HTTP; consult your chosen version's documentation for other SDKs and modes.

Scenario quality depends on modeled users and actions, dynamic data flow, and success criteria rather than code volume. A latency chart without content checks may reflect fast error responses instead of useful application work.

When this approach helps

Suppose a team develops catalog and checkout APIs. The scenario evolves with the contract, and regular version comparisons are required. Code makes load logic reviewable and preserves its exact version alongside results.

Maintenance still costs effort. Someone must understand the SDK, data format, and application architecture. The tool is justified when the team can maintain scenarios after the first run. A one-off recording and forgotten report do not create a sustainable performance process.

Simulation structure

Simulation combines protocol settings, scenarios, injection profiles, and final assertions. A scenario describes an action sequence. Session stores data for one virtual user; checks extract or validate response values. Shared mutable variables outside Session can accidentally mix user data.

Request names should stay stable. Including every product ID in a metric name fragments reports into many rows. Preserve data links for diagnosis while grouping statistics by operation meaning: read product, create cart, or confirm order.

A minimal Java scenario

Place the following code in CatalogSimulation.java within a configured Gatling Java Maven project. On your own environment, /api/catalog returns JSON with an items array. The 500 ms threshold is illustrative; replace it with an agreed criterion.

java
import io.gatling.javaapi.core.Simulation;
import static io.gatling.javaapi.core.CoreDsl.*;
import static io.gatling.javaapi.http.HttpDsl.*;

public class CatalogSimulation extends Simulation {
  {
    var protocol = http.baseUrl(
        System.getProperty("baseUrl", "https://qa.example.test"));
    var catalog = scenario("Catalog reads")
        .exec(http("catalog")
            .get("/api/catalog")
            .check(status().is(200), jsonPath("$.items").exists()));

    setUp(catalog.injectOpen(constantUsersPerSec(5).during(60)))
        .protocols(protocol)
        .assertions(
            global().failedRequests().percent().lt(1.0),
            global().responseTime().percentile(95.0).lt(500));
  }
}
shell
mvn gatling:test -Dgatling.simulationClass=CatalogSimulation -DbaseUrl=https://qa.example.test

The project needs compatible SDK and Maven plugin dependencies. The example has no package; if you add one, change simulationClass to the fully qualified class name. Run a single-user smoke check before applying the specified load.

Open and closed models

The example's injectOpen starts new users at a specified rate. Each sends one request, so user and request arrival rates are approximately equal in this simple model. Adding multiple steps removes that equivalence. The duration of active journeys also affects concurrent user counts.

A closed model specifies concurrent users. As the server slows, users remain in their journeys longer and start new work less frequently. Choose the model based on the load source. A fixed client population and an independent external order stream answer different system questions.

Feeders and test data

A feeder supplies action values such as search strings, products, and accounts. Its distribution mode must suit the data. Reusing a product for reads is usually acceptable; concurrent login to one account may violate session limits and distort results.

Estimate row capacity and exhaustion behavior before execution. Scenarios should not stop unexpectedly during measurement because data runs out. Distributed runs also need a strategy to prevent mutable-record conflicts between generators when operations require uniqueness.

Correlation and checks

After creating a cart, extract its ID into Session and use it in the add-product request. Check extraction success and stop meaningless chains after critical errors. Otherwise, secondary failures fill the report and hide the original cause.

The minimal example checks only that items exists. For a real catalog, add type and significant business-value checks. For checkout, confirm the final total and object state through the contract. Latency assertions cannot compensate for weak response validation.

Pauses and operation duration

Pause models time between meaningful user actions. If users normally read a product page, omitting that pause may overstate activity per user. Conversely, human pauses are usually inappropriate for machine-generated request streams.

Distinguish scenario duration including waits from individual request latency. Adding a pause does not slow the server, but changes intensity and concurrency. Reports should clearly identify measured durations and the actions included in a business transaction.

Monitoring and evidence

Observe generator resources, active connections, and networking. On the server, monitor CPU, memory, databases, pools, and queues. A saturated generator can cause latency and an unmet arrival rate that should not automatically be blamed on the application. Confirm that actual load matches the declared profile.

Save code, parameters, versions, data, and observation intervals. Keep other conditions comparable when comparing builds. If database volume and scenario design also changed, the difference cannot honestly be attributed solely to the new build's performance regression.

Mistakes and interpretation

Common mistakes include confusing arrival rate with concurrency, sharing one token among all users, treating any JSON as success, and focusing only on an aggregate percentile. A short run also does not establish long-term stability or reveal every data-accumulation effect.

For this scenario, a useful conclusion is specific: catalog reads met the selected thresholds at the stated operation arrival rate and environment configuration. Threshold violations require error and resource analysis. Gatling makes that conclusion reproducible but does not choose business criteria for the team.

Further reading