Skip to content

Gatling Performance Testing Cheatsheet

Installation

Platform Command
Ubuntu/Debian wget https://repo1.maven.org/maven2/io/gatling/highcharts/gatling-charts-highcharts-bundle/3.10.3/gatling-charts-highcharts-bundle-3.10.3-bundle.zip && unzip gatling-charts-highcharts-bundle-3.10.3-bundle.zip && sudo mv gatling-charts-highcharts-bundle-3.10.3 /opt/gatling
macOS (Homebrew) brew install gatling
Windows (Manual) Download from Maven Central, extract to C:\gatling, add bin directory to PATH
SDKMAN (Linux/Mac) sdk install gatling
Docker docker pull denvazh/gatling:latest
Maven Plugin Add io.gatling:gatling-maven-plugin:4.6.0 to pom.xml
Gradle Plugin Add id 'io.gatling.gradle' version '3.10.3' to build.gradle

Prerequisites

# Install Java 11+ (required)
sudo apt install openjdk-11-jdk -y  # Ubuntu/Debian
brew install openjdk@11              # macOS

# Verify Java installation
java -version

Basic Commands

Command Description
gatling.sh Launch interactive mode to select and run simulations
gatling.sh -s com.example.MySimulation Run a specific simulation class
gatling.bat -s com.example.MySimulation Run simulation on Windows
gatling.sh --help Display help and available options
gatling.sh --version Show Gatling version
recorder.sh Launch Gatling Recorder GUI for recording browser sessions
recorder.bat Launch Recorder on Windows
gatling.sh -ro simulation-folder-name Generate reports from existing simulation logs
gatling.sh -s MySimulation -nr Run simulation without generating reports
gatling.sh -s MySimulation -rd "Test description" Run with custom description for reports
mvn gatling:test Run all Gatling tests using Maven
mvn gatling:test -Dgatling.simulationClass=MySimulation Run specific simulation with Maven
gradle gatlingRun Run all Gatling tests using Gradle
gradle gatlingRun-com.example.MySimulation Run specific simulation with Gradle
ls user-files/simulations/ List available simulation files

Advanced Usage

Command Description
gatling.sh -s MySimulation -rf /custom/results Run with custom results folder
gatling.sh -s MySimulation -bf /custom/binaries Run with custom binaries directory
gatling.sh -s MySimulation -rsf /custom/resources Run with custom resources directory
gatling.sh -s MySimulation -df /custom/data Run with custom data directory
gatling.sh -s MySimulation -cf /path/to/gatling.conf Run with custom configuration file
JAVA_OPTS="-Xms2G -Xmx4G" gatling.sh -s MySimulation Run with custom JVM memory settings
gatling.sh -s MySimulation -D baseUrl=https://api.example.com Pass system properties to simulation
gatling.sh -s MySimulation -D users=100 -D duration=300 Pass multiple system properties
mvn gatling:test -Dgatling.jvmArgs="-Xms2G -Xmx4G" Maven run with custom JVM arguments
docker run -v $(pwd)/user-files:/opt/gatling/user-files denvazh/gatling Run Gatling in Docker container
gatling.sh -s Sim1 && gatling.sh -s Sim2 Run multiple simulations sequentially
for sim in Sim1 Sim2; do gatling.sh -s $sim -nr; done Batch run simulations without reports
mvn clean gatling:test -DbaseUrl=https://prod.example.com Maven run with environment-specific URL
gradle gatlingRun -Dusers=500 -Dduration=600 Gradle run with dynamic parameters
gatling.sh -s MySimulation 2>&1 | tee test.log Run and capture output to log file

Configuration

Main Configuration File (gatling.conf)

gatling {
  core {
    # Output directory for results
    outputDirectoryBaseName = "simulation"

    # Encoding for files
    encoding = "utf-8"

    # Timeout for requests
    timeOut = 60000

    # Directory for simulation classes
    simulationClass = ""
  }

  http {
    # Enable/disable SSL/TLS
    enableGA = false

    # Connection timeout
    connectTimeout = 10000

    # Request timeout
    requestTimeout = 60000

    # Max connections per host
    maxConnectionsPerHost = 6
  }

  data {
    # Directory for feeder files
    file {
      bufferSize = 256
    }
  }

  charting {
    # Indicators percentiles
    indicators {
      lowerBound = 800
      higherBound = 1200
      percentile1 = 50
      percentile2 = 75
      percentile3 = 95
      percentile4 = 99
    }
  }
}

System Properties Configuration

# Set via command line
gatling.sh -s MySimulation \
  -Dgatling.core.outputDirectoryBaseName=custom-output \
  -Dgatling.http.requestTimeout=30000 \
  -Dgatling.charting.indicators.percentile1=90

Maven Configuration (pom.xml)

<plugin>
    <groupId>io.gatling</groupId>
    <artifactId>gatling-maven-plugin</artifactId>
    <version>4.6.0</version>
    <configuration>
        <simulationClass>com.example.MySimulation</simulationClass>
        <jvmArgs>
            <jvmArg>-Xms2G</jvmArg>
            <jvmArg>-Xmx4G</jvmArg>
            <jvmArg>-XX:+UseG1GC</jvmArg>
        </jvmArgs>
        <systemProperties>
            <baseUrl>https://api.example.com</baseUrl>
            <users>100</users>
        </systemProperties>
    </configuration>
</plugin>

Gradle Configuration (build.gradle)

gatling {
    simulations = {
        include 'com/example/**/*Simulation.scala'
    }

    jvmArgs = ['-Xms2G', '-Xmx4G', '-XX:+UseG1GC']

    systemProperties = [
        'baseUrl': 'https://api.example.com',
        'users': '100'
    ]
}

Common Use Cases

Use Case 1: Basic API Load Test

# Create simulation file
cat > user-files/simulations/BasicApiTest.scala << 'EOF'
import io.gatling.core.Predef._
import io.gatling.http.Predef._
import scala.concurrent.duration._

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

  val scn = scenario("Basic API Test")
    .exec(http("Get Users")
      .get("/users")
      .check(status.is(200)))
    .pause(1)

  setUp(
    scn.inject(
      rampUsers(100) during (60 seconds)
    )
  ).protocols(httpProtocol)
}
EOF

# Run the test
gatling.sh -s BasicApiTest

# View results
open results/basicapitest-*/index.html  # macOS
xdg-open results/basicapitest-*/index.html  # Linux

Use Case 2: Stress Testing with Gradual Load

# Create stress test simulation
cat > user-files/simulations/StressTest.scala << 'EOF'
import io.gatling.core.Predef._
import io.gatling.http.Predef._
import scala.concurrent.duration._

class StressTest extends Simulation {
  val httpProtocol = http.baseUrl("https://api.example.com")

  val scn = scenario("Stress Test")
    .exec(http("Heavy Endpoint")
      .post("/api/process")
      .body(StringBody("""{"data": "test"}"""))
      .check(status.is(200)))

  setUp(
    scn.inject(
      nothingFor(5 seconds),
      atOnceUsers(10),
      rampUsers(50) during (30 seconds),
      constantUsersPerSec(20) during (60 seconds),
      rampUsersPerSec(20) to 50 during (60 seconds)
    )
  ).protocols(httpProtocol)
    .maxDuration(5 minutes)
    .assertions(
      global.responseTime.max.lt(5000),
      global.successfulRequests.percent.gt(95)
    )
}
EOF

# Run with custom memory settings
JAVA_OPTS="-Xms4G -Xmx8G" gatling.sh -s StressTest

Use Case 3: CI/CD Integration with Maven

# Add to Jenkins/GitLab CI pipeline
mvn clean gatling:test \
  -Dgatling.simulationClass=com.example.PerformanceTest \
  -DbaseUrl=${TEST_URL} \
  -Dusers=${CONCURRENT_USERS} \
  -Dduration=${TEST_DURATION}

# Check exit code for pass/fail
if [ $? -eq 0 ]; then
  echo "Performance test passed"
else
  echo "Performance test failed"
  exit 1
fi

# Archive results
tar -czf gatling-results.tar.gz target/gatling/

Use Case 4: Recording Browser Session

# Start recorder
recorder.sh

# Configure in GUI:
# - Listening Port: 8000
# - Output folder: user-files/simulations
# - Class name: RecordedSimulation

# Configure browser proxy to localhost:8000
# Perform actions in browser
# Stop recording

# Run recorded simulation
gatling.sh -s RecordedSimulation

Use Case 5: Data-Driven Testing with Feeders

# Create CSV data file
cat > user-files/resources/users.csv << 'EOF'
username,password
user1,pass1
user2,pass2
user3,pass3
EOF

# Create simulation with feeder
cat > user-files/simulations/DataDrivenTest.scala << 'EOF'
import io.gatling.core.Predef._
import io.gatling.http.Predef._

class DataDrivenTest extends Simulation {
  val httpProtocol = http.baseUrl("https://api.example.com")

  val feeder = csv("users.csv").circular

  val scn = scenario("Login Test")
    .feed(feeder)
    .exec(http("Login")
      .post("/login")
      .body(StringBody("""{"username":"${username}","password":"${password}"}"""))
      .check(status.is(200)))

  setUp(scn.inject(atOnceUsers(10))).protocols(httpProtocol)
}
EOF

# Run test
gatling.sh -s DataDrivenTest

Best Practices

  • Use Appropriate Load Profiles: Start with gradual ramp-up (rampUsers) rather than atOnceUsers to simulate realistic traffic patterns and avoid overwhelming the system immediately

  • Set Realistic Timeouts: Configure connection and request timeouts based on your SLAs (e.g., requestTimeout = 30000 for 30 seconds) to catch performance issues early

  • Implement Proper Assertions: Add assertions to automatically fail tests when performance degrades (global.responseTime.percentile3.lt(2000) ensures 95th percentile under 2 seconds)

  • Use Feeders for Dynamic Data: Leverage CSV, JSON, or custom feeders instead of hardcoding test data to simulate real user behavior and avoid cache hits

  • Allocate Sufficient Memory: For large-scale tests, increase JVM heap size (-Xms4G -Xmx8G) to prevent OutOfMemory errors and ensure smooth execution

  • Monitor System Resources: Watch CPU, memory, and network usage on both load generator and target system during tests to identify bottlenecks accurately

  • Run Tests from Production-Like Environment: Execute load tests from infrastructure similar to production (network latency, bandwidth) for accurate results

  • Version Control Your Simulations: Store simulation code in Git alongside application code to track changes and enable collaboration

  • Separate Concerns with Scenarios: Break complex tests into multiple scenarios and chains for better maintainability and reusability

  • Analyze Reports Thoroughly: Don't just check response times—examine request distribution, error rates, and response time percentiles to understand full performance picture

Troubleshooting

Issue Solution
OutOfMemoryError during test execution Increase JVM heap size: JAVA_OPTS="-Xms4G -Xmx8G" gatling.sh -s MySimulation or reduce concurrent users
"Simulation class not found" error Ensure simulation is in user-files/simulations/ and class name matches file name. Recompile if needed: mvn clean compile
Connection timeout errors Increase timeout in gatling.conf: gatling.http.connectTimeout = 30000 or check network connectivity to target system
SSL/TLS certificate errors Disable certificate validation in simulation: .disableCaching.disableWarmUp.shareConnections.silentResources or add certificate to Java keystore
Recorder proxy not working Check browser proxy settings (localhost:8000), ensure recorder is running, verify no other proxy/VPN is interfering
Reports not generating Check disk space, verify write permissions on results directory, ensure test completed successfully without crashes
High response times on load generator Load generator is overloaded—reduce concurrent users, increase resources, or use distributed testing with multiple generators
"Too many open files" error (Linux) Increase file descriptor limit: ulimit -n 65536 before running Gatling, or add to /etc/security/limits.conf
Simulations compile but don't run Check for syntax errors in Scala code, verify all imports are correct, ensure Gatling version compatibility
Maven/Gradle plugin not found Update plugin version in pom.xml/build.gradle, run mvn clean install or gradle clean build, check Maven Central connectivity
Inconsistent results between runs Warm up target system first, ensure consistent test environment, check for external factors (other traffic, scheduled jobs)
WebSocket connection failures Verify WebSocket protocol in simulation: .ws("Connect").connect("/socket"), check target server WebSocket support
Feeder file not found Place CSV/JSON files in user-files/resources/, use relative path: csv("data.csv") not absolute path
Docker container exits immediately Mount volumes correctly: -v $(pwd)/user-files:/opt/gatling/user-files, ensure simulation files exist in mounted directory

Quick Reference: Load Injection Profiles

// Immediate load
atOnceUsers(100)

// Gradual ramp-up
rampUsers(100) during (60 seconds)

// Constant rate
constantUsersPerSec(20) during (5 minutes)

// Gradual rate increase
rampUsersPerSec(10) to 50 during (2 minutes)

// Staircase pattern
incrementUsersPerSec(5)
  .times(5)
  .eachLevelLasting(30 seconds)
  .separatedByRampsLasting(10 seconds)
  .startingFrom(10)

// Complex scenario
nothingFor(5 seconds),
atOnceUsers(10),
rampUsers(50) during (30 seconds),
constantUsersPerSec(20) during (60 seconds)

Useful File Locations

Path Description
user-files/simulations/ Simulation Scala files
user-files/resources/ Feeder data files (CSV, JSON)
user-files/bodies/ Request body templates
results/ Generated HTML reports
conf/gatling.conf Main configuration file
conf/logback.xml Logging configuration
target/gatling/ Maven build output and reports
build/reports/gatling/ Gradle build output and reports