Babysitter gatling-load-testing
Expert skill for Gatling simulation development, load test execution, and performance analysis. Write Gatling simulations in Scala DSL, configure injection profiles and feeders, define assertions, analyze HTML reports, and integrate with Gatling Enterprise.
git clone https://github.com/a5c-ai/babysitter
T=$(mktemp -d) && git clone --depth=1 https://github.com/a5c-ai/babysitter "$T" && mkdir -p ~/.claude/skills && cp -r "$T/library/specializations/performance-optimization/skills/gatling-load-testing" ~/.claude/skills/a5c-ai-babysitter-gatling-load-testing && rm -rf "$T"
library/specializations/performance-optimization/skills/gatling-load-testing/SKILL.mdgatling-load-testing
You are gatling-load-testing - a specialized skill for Gatling load test development and performance analysis. This skill provides expert capabilities for building comprehensive load testing suites using Gatling's powerful Scala DSL.
Overview
This skill enables AI-powered load testing operations including:
- Writing Gatling simulations in Scala DSL
- Configuring injection profiles (ramp-up, steady, spike, stress)
- Designing feeders for test data management
- Defining assertions and response time percentiles
- Analyzing Gatling HTML reports
- Session handling and correlation
- Gatling Enterprise integration
Prerequisites
- Java 11+ or Java 17+ (recommended)
- Scala 2.13+ or Gatling Bundle
- Maven or Gradle for build management
- Optional: Gatling Enterprise license for advanced features
Capabilities
1. Gatling Simulation Development
Write comprehensive Gatling simulations:
package simulations import io.gatling.core.Predef._ import io.gatling.http.Predef._ import scala.concurrent.duration._ class ApiLoadSimulation extends Simulation { // HTTP Protocol Configuration val httpProtocol = http .baseUrl("https://api.example.com") .acceptHeader("application/json") .contentTypeHeader("application/json") .userAgentHeader("Gatling/LoadTest") .shareConnections .maxConnectionsPerHost(10) // Test Data Feeder val userFeeder = csv("users.csv").circular val searchFeeder = jsonFile("searches.json").random // Request Chains val authenticate = exec( http("Authenticate") .post("/auth/login") .body(StringBody("""{"username":"${username}","password":"${password}"}""")) .check( status.is(200), jsonPath("$.token").saveAs("authToken"), responseTimeInMillis.lte(500) ) ) val searchProducts = exec( http("Search Products") .get("/products/search") .queryParam("q", "${searchTerm}") .header("Authorization", "Bearer ${authToken}") .check( status.is(200), jsonPath("$.results[*]").count.gte(1), responseTimeInMillis.lte(1000) ) ) val viewProduct = exec( http("View Product") .get("/products/${productId}") .header("Authorization", "Bearer ${authToken}") .check( status.is(200), jsonPath("$.id").is("${productId}"), responseTimeInMillis.lte(300) ) ) // Scenario Definition val userJourney = scenario("User Journey") .feed(userFeeder) .exec(authenticate) .pause(1, 3) .feed(searchFeeder) .exec(searchProducts) .pause(500.milliseconds, 2.seconds) .repeat(3) { exec(viewProduct) .pause(1, 2) } // Load Profile setUp( userJourney.inject( rampUsers(100).during(60.seconds), constantUsersPerSec(50).during(300.seconds), rampUsersPerSec(50).to(100).during(120.seconds) ) ).protocols(httpProtocol) .assertions( global.responseTime.percentile3.lt(1000), global.successfulRequests.percent.gte(99), forAll.failedRequests.percent.lt(1) ) }
2. Injection Profiles
Configure various load patterns:
// Ramp-up load pattern setUp( scenario.inject( rampUsers(1000).during(10.minutes) ) ) // Constant load with warm-up setUp( scenario.inject( nothingFor(5.seconds), atOnceUsers(10), rampUsers(100).during(1.minute), constantUsersPerSec(50).during(5.minutes) ) ) // Stress test pattern setUp( scenario.inject( incrementUsersPerSec(10) .times(5) .eachLevelLasting(2.minutes) .separatedByRampsLasting(30.seconds) .startingFrom(10) ) ) // Spike test pattern setUp( scenario.inject( constantUsersPerSec(20).during(2.minutes), stressPeakUsers(500).during(30.seconds), constantUsersPerSec(20).during(2.minutes) ) ) // Soak/Endurance test setUp( scenario.inject( rampUsersPerSec(1).to(30).during(5.minutes), constantUsersPerSec(30).during(4.hours) ) )
3. Feeders and Test Data
Manage test data effectively:
// CSV Feeder val csvFeeder = csv("data/users.csv").circular // JSON Feeder val jsonFeeder = jsonFile("data/products.json").random // JDBC Feeder val jdbcFeeder = jdbcFeeder( "jdbc:postgresql://localhost:5432/testdb", "postgres", "password", "SELECT id, email FROM users WHERE active = true" ) // Custom Feeder val customFeeder = Iterator.continually(Map( "orderId" -> java.util.UUID.randomUUID().toString, "timestamp" -> System.currentTimeMillis(), "amount" -> (100 + scala.util.Random.nextInt(900)) )) // Batch Feeder with transformation val transformedFeeder = csv("data/raw.csv") .transform { case (key, value) => if (key == "amount") (value.toDouble * 1.1).toString else value } .batch(100) .random
4. Session Handling and Correlation
Handle dynamic values and session state:
// Extract and reuse values exec( http("Get CSRF Token") .get("/form") .check( css("input[name='csrf']", "value").saveAs("csrfToken") ) ) .exec( http("Submit Form") .post("/submit") .formParam("csrf", "${csrfToken}") .formParam("data", "${userData}") ) // JSON path extraction exec( http("Get Order") .get("/orders/${orderId}") .check( jsonPath("$.items[*].id").findAll.saveAs("itemIds"), jsonPath("$.total").saveAs("orderTotal") ) ) .foreach("${itemIds}", "itemId") { exec( http("Get Item Details") .get("/items/${itemId}") ) } // Conditional execution exec(session => { if (session("userType").as[String] == "premium") { session.set("rateLimit", 1000) } else { session.set("rateLimit", 100) } }) .doIf("${userType}", "premium") { exec(premiumFeatures) }
5. Assertions and Thresholds
Define comprehensive assertions:
setUp(scenario.inject(/* ... */)) .protocols(httpProtocol) .assertions( // Global assertions global.responseTime.max.lt(5000), global.responseTime.mean.lt(500), global.responseTime.percentile1.lt(200), // P50 global.responseTime.percentile2.lt(500), // P75 global.responseTime.percentile3.lt(1000), // P95 global.responseTime.percentile4.lt(2000), // P99 // Success rate assertions global.successfulRequests.percent.gte(99.5), global.failedRequests.count.lt(100), // Request-specific assertions details("Authenticate").responseTime.percentile3.lt(500), details("Search Products").successfulRequests.percent.gte(99), // Throughput assertions global.requestsPerSec.gte(1000) )
6. Report Analysis
Analyze Gatling HTML reports:
// Report configuration .protocols(httpProtocol) .pauses(constantPauses) // Custom report naming System.setProperty("gatling.core.outputDirectoryBaseName", "api-load-test") System.setProperty("gatling.charting.indicators.lowerBound", "800") System.setProperty("gatling.charting.indicators.higherBound", "1200")
Key metrics to analyze:
- Response Time Distribution: P50, P75, P95, P99
- Active Users Over Time: Concurrency levels
- Requests Per Second: Throughput trends
- Response Time Percentiles Over Time: Performance degradation
- Errors: Failure patterns and error codes
MCP Server Integration
This skill can leverage the following MCP servers:
| Server | Description | Use Case |
|---|---|---|
| locust-mcp | Load testing MCP | Alternative load testing execution |
| playwright-mcp | Browser automation | UI-based load testing scenarios |
Best Practices
Simulation Design
- Realistic scenarios - Model actual user behavior
- Think time - Include realistic pauses between actions
- Data variation - Use diverse test data
- Session isolation - Avoid shared state between users
Performance
- Connection pooling - Use
shareConnections - Feeder optimization - Use appropriate feeder strategies
- Resource management - Monitor Gatling JVM resources
- Distributed execution - Scale across multiple injectors
Assertions
- Multiple percentiles - Don't rely only on averages
- Error thresholds - Set acceptable failure rates
- Baseline comparison - Compare against known good runs
- Business SLOs - Align with actual SLOs
Process Integration
This skill integrates with the following processes:
- Initial Gatling setupload-testing-framework-setup.js
- Test execution and orchestrationload-test-execution.js
- Stress test scenario designstress-testing-analysis.js
Output Format
When executing operations, provide structured output:
{ "operation": "run-simulation", "status": "completed", "simulation": { "name": "ApiLoadSimulation", "duration": "300s", "totalUsers": 5000 }, "results": { "requestCount": 150000, "errorCount": 45, "errorRate": "0.03%", "responseTime": { "mean": 245, "p50": 180, "p75": 320, "p95": 890, "p99": 1450, "max": 4200 }, "throughput": 500.5 }, "assertions": { "passed": 8, "failed": 0 }, "reportPath": "target/gatling/apisimulation-20260124/index.html" }
Error Handling
Common Issues
| Error | Cause | Resolution |
|---|---|---|
| Target unavailable | Verify target URL and network |
| Slow target | Increase timeout, check target capacity |
| Too many users | Increase heap, distribute load |
| Insufficient test data | Use or |
| Missing extraction | Verify check expressions |
Constraints
- Verify target system can handle load before testing
- Coordinate with operations team for production-like tests
- Monitor injector resources during tests
- Use appropriate test data (not production data)
- Consider network latency in distributed setups