07 — Injection Profiles
The injection profile controls how many virtual users are created and when. This is the most important tuning knob for realistic load tests.
Open vs closed workload models
| Model | Concept | Use when |
|---|---|---|
| Open | You control the arrival rate (users/sec). Queue builds up if the server is slow. | Most web apps — users arrive regardless of server speed |
| Closed | You control the concurrency (active users at any time). New user starts only when another finishes. | Connection pools, queue processors |
Open workload — injectOpen
atOnceUsers(n)
Inject all users simultaneously. Good for spike tests.
rampUsers(n).during(duration)
Linearly ramp up from 0 to n users over the duration.
// Java
scn.injectOpen(rampUsers(500).during(Duration.ofSeconds(60)))
// Kotlin
scn.injectOpen(rampUsers(500).during(60))
constantUsersPerSec(rate).during(duration)
Inject users at a constant rate (users/second).
rampUsersPerSec(from).to(to).during(duration)
Ramp the arrival rate from one value to another.
stressPeakUsers(n).during(duration)
Inject users with a "stress peak" shape (Heaviside step function) — quickly ramps to n over the duration.
nothingFor(duration)
Pause before the next injection stage.
Chaining injection steps
Pass multiple steps to injectOpen — they execute sequentially:
// Java
scn.injectOpen(
atOnceUsers(10), // initial spike
nothingFor(Duration.ofSeconds(10)), // cooldown
rampUsers(100).during(Duration.ofSeconds(60)), // ramp up
constantUsersPerSec(20.0).during(Duration.ofMinutes(5)), // steady state
rampUsersPerSec(20.0).to(0.0).during(Duration.ofSeconds(30)) // ramp down
)
// Kotlin
scn.injectOpen(
atOnceUsers(10),
nothingFor(10),
rampUsers(100).during(60),
constantUsersPerSec(20.0).during(Duration.ofMinutes(5)),
rampUsersPerSec(20.0).to(0.0).during(30)
)
Closed workload — injectClosed
constantConcurrentUsers(n).during(duration)
Maintain exactly n concurrent users for the duration.
rampConcurrentUsers(from).to(to).during(duration)
Gradually change concurrency.
Multiple scenarios in parallel
Wire multiple scenarios in one setUp:
// Java
setUp(
readers.injectOpen(constantUsersPerSec(50).during(Duration.ofMinutes(10))),
writers.injectOpen(constantUsersPerSec(5).during(Duration.ofMinutes(10)))
).protocols(httpProtocol);
// Kotlin
setUp(
readers.injectOpen(constantUsersPerSec(50.0).during(Duration.ofMinutes(10))),
writers.injectOpen(constantUsersPerSec(5.0).during(Duration.ofMinutes(10)))
).protocols(httpProtocol)
Throttling (rate limiter)
Throttling caps the global request rate, independent of the number of users. Useful when you want to stay under an SLA or quota.
setUp(
scn.injectOpen(rampUsers(1000).during(Duration.ofSeconds(30)))
)
.protocols(httpProtocol)
.throttle(
reachRps(100).in(Duration.ofSeconds(10)), // ramp to 100 RPS over 10 s
holdFor(Duration.ofMinutes(5)), // hold at 100 RPS for 5 min
jumpToRps(200), // immediately jump to 200 RPS
holdFor(Duration.ofMinutes(2))
);
Maximum simulation duration
Gatling runs until all users finish. Set a hard cap to avoid runaway tests:
Common profiles
Smoke test
Load test (ramp + steady)
scn.injectOpen(
rampUsers(200).during(Duration.ofSeconds(60)),
constantUsersPerSec(10.0).during(Duration.ofMinutes(10))
)
Stress test (keep increasing until breakpoint)
Spike test
scn.injectOpen(
constantUsersPerSec(5.0).during(Duration.ofMinutes(5)),
atOnceUsers(500), // sudden spike
constantUsersPerSec(5.0).during(Duration.ofMinutes(5))
)