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 thanatOnceUsersto 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 = 30000for 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 |