At high VU counts (typically 5000+), dial tcp: i/o timeout errors appear even when the load generator has healthy CPU and memory and OS tuning has been applied. This is TCP connection pool exhaustion — a different problem from CPU/RAM saturation.
Signals
http_req_blockedavg is in the seconds range — measures time waiting for a free socket; high value means the connection pool is exhaustedhttp_req_connectingp(90) is very high (e.g. 15s) — at least 10% of connections are taking seconds just to establishiteration_durationavg is much higher than expected — VUs are spending most of their time blocked, not executing requestshttp_req_failedrate is high despite healthy generator CPU/memory
Common errors
| Error | Cause |
|---|---|
dial tcp: i/o timeout | TCP connection timed out — ran out of available ports or the SUT dropped the connection |
connection reset by peer | Server closed the connection, likely due to its own connection limit or timeout |
unexpected EOF | Connection dropped mid-response |
context deadline exceeded | Request exceeded k6’s default 60s timeout |
res.status === 0 means k6 could not complete the request. The accompanying error field explains why.
gracefulStop and interrupted iterations
dial tcp: i/o timeout errors appearing at the very end of a test (e.g. WARN[0033] in a --duration=1s run) are often from interrupted iterations, not the test body itself.
k6 defaults to gracefulStop: 30s — VUs that haven’t finished their iteration when the test duration ends get 30 more seconds to complete. Connections opened during this window are still subject to limits, and if the SUT is already stressed, they time out.
Tip
If errors only appear near the end of the test, increase
gracefulStopin a scenario config to give VUs more time to finish, or investigate why iterations are taking so long in the first place.
SUT vs generator
OS tuning (ip_local_port_range, tcp_tw_reuse, ulimit -n) addresses the load generator’s limits. But the bottleneck may be on the SUT side:
- AWS API Gateway + Lambda: AWS throttles concurrent Lambda invocations. At 5k+ VUs, the gateway may start dropping or delaying connections before the generator hits its own limits.
- Any SUT: check CPU, memory, and connection logs on the target system, not just the generator. Use
dmesgor syslog on both machines for kernel-level connection errors.
The only way to distinguish generator-side from SUT-side exhaustion is to monitor both simultaneously during the test.
See also
- k6-vu-saturation — CPU/RAM saturation on the load generator
- k6-os-tuning — OS-level tuning for high VU counts
- k6-large-tests — distributed execution when a single machine isn’t enough