Injection profiles control how virtual users enter your simulation. This is the equivalent of JMeter's Thread Group configuration -- thread count, ramp-up period, loop count. But Gatling gives you much more fine-grained control. Instead of just "100 threads with 60 second ramp-up," you can build complex multi-phase load patterns that model real-world traffic.
This is a concept JMeter does not distinguish. Gatling has two injection models. Open model (injectOpen): users arrive at a rate independent of server response. Even if the server is slow, new users keep arriving. This models real-world web traffic where users do not wait in a queue to access your site. Closed model (injectClosed): a fixed number of concurrent users. When one finishes, another starts. This models scenarios like call centers where there is a fixed capacity. For web and API testing, you almost always want the open model.
// 1. Ramp users: gradually add N users over a duration
scenario.injectOpen(
rampUsers(100).during(Duration.ofSeconds(60)) // 0 to 100 users over 60s
)
// 2. At once: all users start simultaneously
scenario.injectOpen(
atOnceUsers(50) // 50 users, right now
)
// 3. Constant rate: N users per second, sustained
scenario.injectOpen(
constantUsersPerSec(10).during(Duration.ofMinutes(2)) // 10 users/sec for 2 min
)
// 4. Ramp rate: gradually increase from X to Y users/sec
scenario.injectOpen(
rampUsersPerSec(1).to(20).during(Duration.ofMinutes(3)) // 1/sec to 20/sec over 3 min
)
// 5. Stress peak: bell curve shaped spike
scenario.injectOpen(
stressPeakUsers(1000).during(Duration.ofSeconds(20)) // 1000 users in a bell curve over 20s
)
// 6. Nothing: wait before starting
scenario.injectOpen(
nothingFor(Duration.ofSeconds(5)), // Wait 5 seconds
atOnceUsers(10) // Then start 10 users
)Real traffic is not a simple ramp. It has warm-up periods, steady states, spikes, and cool-downs. Gatling lets you chain injection steps to model complex patterns.
// Load test: ramp up, sustain, ramp down
scenario.injectOpen(
rampUsers(200).during(Duration.ofMinutes(2)), // Warm up: 0 to 200
constantUsersPerSec(20).during(Duration.ofMinutes(5)),// Steady: 20/sec for 5 min
rampUsers(0).during(Duration.ofMinutes(1)) // Cool down
)
// Spike test: normal traffic then sudden burst
scenario.injectOpen(
constantUsersPerSec(10).during(Duration.ofMinutes(2)), // Normal: 10/sec for 2 min
stressPeakUsers(1000).during(Duration.ofSeconds(30)), // SPIKE: 1000 users in 30s
nothingFor(Duration.ofMinutes(1)), // Wait for recovery
constantUsersPerSec(10).during(Duration.ofMinutes(2)) // Back to normal
)
// Stress test: staircase pattern
scenario.injectOpen(
// Step 1: 100 users
rampUsers(100).during(Duration.ofSeconds(30)),
nothingFor(Duration.ofMinutes(2)),
// Step 2: 200 users
rampUsers(200).during(Duration.ofSeconds(30)),
nothingFor(Duration.ofMinutes(2)),
// Step 3: 500 users
rampUsers(500).during(Duration.ofSeconds(30)),
nothingFor(Duration.ofMinutes(2)),
// Step 4: 1000 users (expect failures here)
rampUsers(1000).during(Duration.ofSeconds(30)),
nothingFor(Duration.ofMinutes(2))
)In real applications, not all users do the same thing. 70% browse, 20% search, 10% buy. You can model this by running multiple scenarios with different injection rates.
{
setUp(
// 70% of users browse
browseScenario.injectOpen(
rampUsers(700).during(Duration.ofMinutes(2)),
constantUsersPerSec(7).during(Duration.ofMinutes(10))
).protocols(httpProtocol),
// 20% of users search
searchScenario.injectOpen(
rampUsers(200).during(Duration.ofMinutes(2)),
constantUsersPerSec(2).during(Duration.ofMinutes(10))
).protocols(httpProtocol),
// 10% of users buy
purchaseScenario.injectOpen(
rampUsers(100).during(Duration.ofMinutes(2)),
constantUsersPerSec(1).during(Duration.ofMinutes(10))
).protocols(httpProtocol)
).assertions(
global().responseTime().percentile(95.0).lt(3000),
global().successfulRequests().percent().gt(99.0)
);
}The open model means that if your server is slow, users pile up. With constantUsersPerSec(100) and a server that responds in 5 seconds, you will have 500 concurrent users at any time (100/sec x 5 sec). If response time degrades to 10 seconds, that becomes 1,000 concurrent. This is realistic but can overwhelm both the server and your Gatling machine. Monitor your Gatling machine resources during tests.
Key Point: Use injectOpen for realistic web traffic. Chain injection steps for complex patterns: ramp up, sustain, spike, recover, cool down. Model user mix with multiple scenarios at different rates.
Key Point: Injection profiles control how users arrive -- chain steps for realistic patterns, use multiple scenarios for user mix