SuperAPI AI Directory

gatling

Design & creation

View repository

Updated 10-15 21:49

About this skill

Gatling

Gatling is a powerful load testing tool. It is designed for ease of use, maintainability, and high performance. It uses an asynchronous (Akka/Netty) architecture that allows generating huge load from a single machine.

When to Use

  • High-Concurrency Load Testing: Simulating tens of thousands of concurrent virtual users with minimal CPU and memory footprints.
  • Performance Regression Gates in CI/CD: Running automated performance assertions against staging environments on every release.
  • Scala / Java / Kotlin / TypeScript Load DSLs: Writing programmatic, version-controlled load testing scenarios as code.
  • Protocol Benchmarking: Stress testing HTTP, WebSockets, Server-Sent Events, and JMS message queues.

Quick Start

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

public class BasicSimulation extends Simulation {

HttpProtocolBuilder httpProtocol = http .baseUrl("http://computer-database.gatling.io") .acceptHeader("application/json");

ScenarioBuilder scn = scenario("BasicSimulation") .exec(http("request_1").get("/computers"));

{ setUp( scn.injectOpen(atOnceUsers(10)) ).protocols(httpProtocol); } }


## Core Concepts

### Non-Blocking Asynchronous Engine (Netty & Akka)

Unlike thread-per-user load tools, Gatling uses non-blocking actors to simulate thousands of users on a single OS thread:

```text
[ Gatling Scenario Engine ] ──(Netty Event Loop)──→ [ Thousands of Async Virtual Users ]

Scenario DSL & Injection Profiles (Java / TypeScript)

Defines user journeys, think times, and virtual user ramp-up profiles:

// Java / Scala Gatling Simulation
import io.gatling.javaapi.core.*;
import io.gatling.javaapi.http.*;
import static io.gatling.javaapi.core.CoreDsl.*;
import static io.gatling.javaapi.http.HttpDsl.*;

public class ApiLoadSimulation extends Simulation {
    HttpProtocolBuilder httpProtocol = http
        .baseUrl("https://api.staging.example.com")
        .acceptHeader("application/json");

    ScenarioBuilder scn = scenario("Browse and Checkout")
        .exec(http("Get Products").get("/products").check(status().is(200)))
        .pause(2)
        .exec(http("Add to Cart").post("/cart").body(StringBody("{"id": 101}")).asJson());

    {
        setUp(
            scn.injectOpen(
                rampUsers(500).during(60) // Ramp up to 500 users over 60 seconds
            )
        ).protocols(httpProtocol)
         .assertions(
             global().responseTime().percentile(95).lt(300), // 95th percentile under 300ms
             global().successfulRequests().percent().gt(99.0) // 99% success rate
         );
    }
}

Feeders for Dynamic Parameterized Test Data

Injects dynamic user credentials and search queries from CSV or JSON files:

FeederBuilder<String> csvFeeder = csv("users.csv").circular();

ScenarioBuilder scn = scenario("User Login")
    .feed(csvFeeder)
    .exec(http("Login")
        .post("/login")
        .formParam("user", "#{username}")
        .formParam("pass", "#{password}"));

Common Patterns

Ramp-up Virtual Users with Latency Assertions

Problem: Sudden spike tests cause immediate connection saturation that masks normal production bottlenecks.

Solution: Use incremental user ramping with percentile assertions:

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

class ApiLoadTest extends Simulation {
  val httpProtocol = http.baseUrl("https://api.example.com")
    .acceptHeader("application/json")

  val scn = scenario("Checkout Workflow")
    .exec(http("Get Products").get("/products"))
    .pause(1)
    .exec(http("Place Order").post("/orders").body(StringBody("{\"item\":\"widget\"}")) .asJson)

  setUp(
    scn.inject(rampUsers(500).during(60.seconds))
  ).protocols(httpProtocol)
   .assertions(
     global.responseTime.percentile3.lt(500),
     global.successfulRequests.percent.gt(99.0)
   )
}

Best Practices

Do:

  • Enforce Service Level Agreements (SLAs) with Assertions: Define explicit assertions on p95/p99 response times and error rates.
  • Ramp Virtual Users Smoothly: Use rampUsers or rampUsersPerSec to allow connection pools and autoscalers to adapt realistically.
  • Model Realistic Think Times: Use pause(min, max) to replicate human user behavior rather than firing continuous request loops.
  • Generate Real-Time Reports with Graphite / InfluxDB: Stream Gatling metrics live into Grafana dashboards during tests.

Don't:

  • Run load tests from the same machine hosting the application: CPU contention corrupts latency measurements.
  • Ignore network bandwidth limits on test runners: Saturated runner network cards artificially degrade response percentiles.
  • Hardcode fixed authentication tokens: Rotate users via feeders to test realistic database index and cache hit rates.

Troubleshooting

Error Cause Solution
java.net.ConnectException: Cannot assign requested address OS ephemeral socket exhaustion on Gatling runner. Increase ephemeral port range and enable TCP TIME_WAIT socket recycling.
i.g.h.c.i.Response: 504 Gateway Timeout Target server overwhelmed under simulated load. Inspect server metrics, connection pool limits, and database query latency.
Gatling simulation compile error Gatling version API mismatch between Gatling 3.x and 3.10+. Check imported packages against official Gatling SDK migration guide.

References