Choosing Between Open and Closed Workload Models in Gatling
Learn how to choose between Open and Closed workload models in Gatling to avoid coordinated omission and simulate realistic user traffic for APIs and internal systems.
05 Apr 2026, 20:39 UTC

The Risk of Coordinated Omission
When simulating traffic, a common mistake is using a workload model that unintentionally synchronizes with the system's response time. This leads to coordinated omission: a scenario where the load generator waits for the System Under Test (SUT) to respond before sending the next request. If the SUT slows down, the load generator slows down too, masking the very latency spikes and throughput drops you are trying to detect.
The decision between an Open and Closed workload model determines whether your test simulates a fixed number of users (Closed) or a fixed rate of arrivals (Open). Choosing the wrong one can result in reports that show stable throughput while your actual users are experiencing timeouts in production.
Comparing Workload Models
| Feature | Closed Model | Open Model |
|---|---|---|
| Primary Driver | Concurrency (Number of Users) | Arrival Rate (Requests per Second) |
| Behavior on Latency Spike | Throughput drops; users wait. | Throughput stays constant; users accumulate. |
| Best Use Case | Internal tools, fixed-seat licenses. | Public APIs, Web storefronts. |
| Risk | Masks bottlenecks (Coordinated Omission). | Load generator resource exhaustion. |
Trade-offs and Decision Logic
The Closed Model (Concurrency-Based)
In a closed model, a new user only starts their scenario once another user has finished. This creates a hard cap on concurrency. Use this model when your system has a physical or logical limit on the number of simultaneous connections, such as a legacy database with a strict connection pool or a corporate application with a fixed number of licensed seats.
The Open Model (Arrival-Based)
An open model triggers new users at a scheduled frequency regardless of whether previous users have completed their tasks. This mimics real-world internet traffic, where a user does not check if your server is lagging before deciding to visit your site. This is the gold standard for public-facing services.
Warning: Because the open model continues to inject users even as the SUT slows down, the number of active concurrent users will climb linearly during a performance degradation. This can lead to OutOfMemoryError on the machine running Gatling if the SUT hangs completely.
Implementation Example
The following example demonstrates how to implement both models using the Gatling Scala DSL (assuming version 3.7+). Run these scripts from your local terminal or CI runner with the necessary permissions to execute Java/Scala binaries.
Scenario Setup
import io.gatling.core.Predef._
import io.gatling.http.Predef._
val scn = scenario("API Test")
.exec(http("Request").get("/api/resource"))
Closed Model Configuration
Use constantUsersPerSec to maintain a specific rate, but remember that if the SUT slows down, the actual throughput will drop.
setUp(
scn.inject(
constantUsersPerSec(10).during(60) // 10 users started per second
)
).protocols(httpProtocol)
Open Model Configuration
Use arrivalRate to decouple the request rate from the SUT response time. This ensures that 10 requests are attempted every second, even if the server takes 10 seconds to respond.
setUp(
scn.inject(
arrivalRate(
every(1.second), atOnceUsers(10) // Exactly 10 arrivals per second
).during(60)
)
).protocols(httpProtocol)
Validating the Result
To verify which model is behaving correctly during a latency spike, monitor the Requests per Second (RPS) in the Gatling report:
- In a Closed Model: If you introduce a 5-second delay in the SUT, you will see the RPS drop significantly below your configured rate.
- In an Open Model: The RPS should remain flat (at your configured
arrivalRate), while the Active Users metric and Response Time (percentiles) will spike upward.
If the RPS drops during a period of high latency in an Open model, check your load generator's CPU and RAM; you may have hit a hardware bottleneck on the testing machine itself.
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.