A production performance testing strategy with Gatling isn’t about finding bottlenecks in your current production environment; it’s about simulating production load before you hit it, to prevent those bottlenecks from ever forming.

Let’s see Gatling in action, simulating a realistic user journey on an e-commerce site. Imagine a user searching for a product, adding it to their cart, and proceeding to checkout.

import io.gatling.core.Predef._
import io.gatling.http.Predef._
import scala.concurrent.duration._

class ECommerceSimulation extends Simulation {

  val httpProtocol = http
    .baseUrl("http://your-ecommerce-site.com")
    .doNotTrack

  val scn = scenario("User Journey")
    .exec(http("Homepage")
      .get("/"))
    .pause(1.seconds, 3.seconds)
    .exec(http("Search Product")
      .get("/products?q=gadget"))
    .pause(2.seconds, 5.seconds)
    .exec(http("Add to Cart")
      .post("/cart")
      .formParam("productId", "12345")
      .formParam("quantity", "1"))
    .pause(1.seconds, 2.seconds)
    .exec(http("View Cart")
      .get("/cart"))
    .pause(3.seconds, 7.seconds)
    .exec(http("Checkout")
      .post("/checkout")
      .formParam("paymentMethod", "creditCard"))

  setUp(
    scn.inject(
      rampUsers(1000) during (30.seconds),
      constantUsersPerSec(200) during (1.minutes)
    ).protocols(httpProtocol)
  ).maxDuration(5.minutes)
}

This script defines a single scenario representing a typical user. It makes a series of HTTP requests: hitting the homepage, searching for a product, adding it to the cart, viewing the cart, and finally initiating checkout. The pause statements inject realistic think times between user actions. The setUp block is where the magic happens: it defines how we inject users. Here, we ramp up to 1000 concurrent users over 30 seconds, then maintain a constant rate of 200 users per second for a full minute. This simulates a sudden surge in traffic followed by a sustained peak.

The core problem Gatling solves in a production performance testing strategy is understanding how your system behaves under expected and peak load conditions. It’s not just about hitting a button and seeing if it breaks; it’s about characterizing its performance. This involves defining realistic user journeys, simulating concurrent user activity, and analyzing the results against predefined Service Level Objectives (SLOs).

Internally, Gatling uses an Akka-based actor system. Each virtual user is an actor, and Gatling orchestrates thousands of these actors to simulate concurrent users. It’s highly efficient because it doesn’t rely on traditional thread-per-user models. The HTTP protocol implementation is built on Netty, a non-blocking I/O client, further enhancing its ability to handle a massive number of concurrent connections without consuming excessive resources. You control the baseUrl, the specific http requests (GET, POST, PUT, DELETE), the request bodies (JSON, form parameters), authentication (headers), and crucially, the injection profiles which dictate the user load over time.

When designing your strategy, start by identifying your critical user journeys. These are the paths users take that are most important for your business. For an e-commerce site, this might be "Browse -> Add to Cart -> Checkout." For a social media app, it could be "Login -> Post -> View Feed." Don’t just simulate page loads; simulate user actions. If your application relies heavily on asynchronous operations, ensure your Gatling scripts reflect this by waiting for specific elements or making subsequent calls that depend on previous ones. For instance, after a successful search, you might need to extract a product ID from the response to use in an "Add to Cart" request.

The constantUsersPerSec injection profile is your go-to for simulating steady-state load, while rampUsers and rampUsersPerSec are excellent for testing how your system scales up and down. The constantConcurrentUsers profile is useful for simulating a fixed number of users who remain active for the duration of the test. Remember to define meaningful assertions on your Gatling reports. These are not just for passing/failing tests; they are your SLOs. Assert that 95% of requests complete within 500ms, or that the error rate remains below 0.1%.

A common mistake is to focus solely on average response times. Gatling’s detailed reports highlight percentiles (90th, 95th, 99th) which are far more indicative of user experience under load. If your 99th percentile response time for adding an item to the cart is 10 seconds, it means a small but significant portion of your users are experiencing a very poor experience, even if the average is acceptable. Pay close attention to the numberOfRequests and totalNumberOfRequests metrics to understand the throughput your system can handle. Also, monitor the malformedRequests and requestsTimeouts to identify fundamental issues.

The next step after understanding your system’s performance under simulated load is to investigate how it behaves when specific downstream services experience latency or failure.

Want structured learning?

Take the full Gatling course →