Scaling Up: Distributed Load Generation and Long-Term Test Maintenance

In the previous post, we automated our tests in a pipeline. This is the last post in the series, and it covers two things that only really become relevant once a framework has been running for a while. Outgrowing a single machine, and keeping the whole thing maintainable months after the initial build. When One Machine Is Not Enough Gatling’s engine is efficient, and a single reasonably sized machine can simulate a genuinely large number of virtual users before it becomes the bottleneck rather than the system under test. That said, at some point, usually when you are stress testing a system designed for very high real world traffic, the load generator itself becomes the limiting factor, not the application you are trying to test. ...

June 11, 2026

Running Gatling in CI/CD: Pipelines and Environment Configuration

In the previous post, we learned to actually read what Gatling produces. None of this is worth much long term if it only ever runs on someone’s laptop before a release, run manually and inconsistently. Today we automate it properly, and we sort out configuration across environments while we are at it, since the two problems tend to show up together in practice. Externalizing the Base URL Every simulation so far has hardcoded a base URL directly in the protocol configuration. That falls apart the moment you want to run the exact same simulation against a local environment, a staging environment, and occasionally production itself for a controlled test. The fix is to read it from a system property instead. ...

May 28, 2026

Reading Gatling Reports: Percentiles, Throughput, and What Actually Matters

In the previous post, we set up assertions so a build fails automatically when performance regresses. A passing build is a good start, but the report itself still holds a lot of useful detail worth understanding properly, especially when something does go wrong and you need to figure out why. Every Gatling run produces a self contained HTML report. Open it with the show command from part one. mvn gatling:test # once the run finishes, Gatling prints the path to the report, # or open the latest one directly under target/gatling/ The Global Stats Page The landing page of the report summarizes the entire simulation. A few numbers here matter more than the rest. The percentile breakdown, shown as a chart and a table, tells you the distribution of response times across every single request in the run, not just an average. The requests per second chart over time shows whether your injection profile actually produced the load shape you intended, which is worth checking even on a passing run, since a misconfigured injection profile can silently produce far less load than you think it did. ...

May 14, 2026

Setting Performance SLAs With Gatling Assertions

In the previous post, we covered the different types of performance tests. Today we cover something that turns any of those tests from “someone eyeballs the report and makes a judgment call” into an objective, automatable pass or fail result. Assertions. Without assertions, a Gatling run finishes and hands you a report, and a human has to decide whether the numbers in it are acceptable. That does not scale, and it definitely does not work inside a CI pipeline where nobody is watching the run happen live. Assertions let you encode your performance requirements directly into the simulation, so the build itself fails when those requirements are not met. ...

April 30, 2026

Load, Stress, Soak, and Spike Testing: Choosing the Right Injection Strategy

In the previous post, we made scenarios behave more like real users. With everything we have built so far, injection profiles, feeders, correlation, checks, and pacing, we finally have enough pieces to talk about the different types of performance tests properly, since “run a load test” actually covers several genuinely different testing goals. Load Testing: Expected Traffic A load test answers a simple question. Does the system perform acceptably under the traffic level you actually expect. This is the baseline test you should have running regularly, ideally on every significant release. ...

April 16, 2026

Modeling Realistic User Journeys: Pacing, Think Time, and Scenario Design

In the previous post, we made sure our checks actually catch real failures. Today we look at something just as important but easier to overlook, whether your scenario actually behaves like a real user in the first place. A scenario that fires request after request with zero delay between them does not represent any real visitor to your site. It represents a script racing through steps as fast as the network allows. That produces load numbers, but not necessarily useful ones, since real traffic has gaps in it while people actually read a page, think about what to click next, or get distracted by something else entirely. ...

April 2, 2026

Checks and Validations: Making Sure Your Load Test Catches Real Failures

In the previous post, we used checks to extract tokens for correlation. This time we look at checks purely from a validation angle, because a surprising number of load tests quietly pass while the application under test is actually broken. The Trap of Checking Status Codes Only Here is a scenario I have seen play out more than once. A test checks only that every response comes back with a 200 status. Midway through the run, the application starts returning a generic error page, but that error page itself happens to render with a 200 status code, because the server is misconfigured to return success even for its own error pages. The load test finishes green. The report shows a great response time. Meanwhile every single user in that window got an error page instead of what they asked for. ...

March 19, 2026

Correlation and Authentication: Extracting Tokens and Handling Login Flows

In the previous post, we fed real data into our scenarios. Today we cover something almost every real application needs before you can test anything interesting behind a login screen. Correlation. Correlation just means grabbing a value out of one response and reusing it in a later request. The most common example by far is authentication. You log in once, get back a token, and then attach that token to every request that follows. ...

March 5, 2026

Feeders 101: Driving Tests With CSV, JSON, and In-Memory Data

In the previous post, we looked at how many users to inject and when. Today we tackle a different problem. If every one of those users logs in with the same username, or adds the exact same product to their cart, you are not really testing realistic load. You are testing one specific code path over and over. Feeders solve this by handing each virtual user its own piece of data before it runs through the scenario. ...

February 19, 2026

Scenarios and Virtual Users: Understanding Injection Profiles

In the previous post, we built a proper chained scenario and separated it cleanly from load setup. Today we focus entirely on that load setup, because how you inject virtual users into a scenario has a huge effect on what your test actually measures. A lot of people new to Gatling reach for atOnceUsers and stop there. It has its place, but it does not represent how real traffic behaves, and using it for everything will give you misleading results. ...

February 5, 2026