Files
spring-async-demo/virtual-threads-benchmark-webflux/docs/output/03-event-loop-starvation.txt
T
Claude b331db6638 Add virtual-threads-benchmark-webflux: the WebFlux leg of the three-way benchmark
Fixes two bugs found during self-correction before publishing:
- /stream used Flux.interval(), which ticks on its own wall-clock schedule
  independent of downstream demand and threw OverflowException under a slow
  subscriber; switched to Flux.range(), which has no independent production
  schedule and can never outrun demand.
- The event-loop-starvation test's first cut used only 8 concurrent /cpu
  requests as background load, which drained through the 4 event-loop
  threads well inside the /io measurement window and produced an
  inconsistent, sometimes-inverted result across runs; raised to 60
  concurrent requests (matching the CPU-bound benchmark's own concurrency)
  so the load actually occupies the event loop for the full window.

Also adds StreamBackpressureTest, a StepVerifier proof that the /stream
endpoint never emits ahead of its subscriber's outstanding requests.
2026-09-19 08:48:58 +00:00

17 lines
1.3 KiB
Plaintext

/io latency while 60 concurrent CPU-bound requests run, 2 vCPU sandbox, Spring Boot 4.1.1 / JDK 25.0.4.1
========================================================================================================
/io alone (baseline, no concurrent CPU load) : total=20 success=20 wall=336ms p50=323ms p99=329ms
/io while 60x /cpu (naive) run concurrently : total=20 success=20 wall=486ms p50=452ms p99=467ms
/io while 60x /cpu-offloaded run concurrently : total=20 success=20 wall=398ms p50=377ms p99=387ms
This is the real cost of the naive endpoint, and it does not show up by benchmarking
/cpu in isolation: /io shares the same small event-loop pool with /cpu. With enough
concurrent CPU load to occupy all 4 event-loop threads for the full measurement
window (a first cut of this test used only 8 concurrent CPU requests, which drained
through the event loop in well under the /io window and produced an inconsistent,
sometimes-inverted result across runs -- fixed by raising the CPU load's own
concurrency, not by changing the assertion), naive /io latency is consistently and
substantially worse than both the undisturbed baseline and the offloaded case. At
higher production concurrency this is the exact mechanism behind a single CPU-heavy
endpoint silently degrading every other endpoint on the same Netty server.