Load, stress and sweep tests with k6: find the knee, check Little's Law, name the bottleneck
catalog gets slow under load. Cache? Replica? Ten more servers? Which one — and how do you know?
catalog
docker stats
vus
*-arrival-rate
dropped_iterations
Coordinated omission: a closed tester skips exactly the requests that would have suffered most.
k6 run -e RATE=200 -e DURATION=1m load/load.js
tomcat.threads.busy
hikaricp.connections.active
hikaricp.connections.pending
bash scripts/watch-metrics.sh http://localhost:8082
Three terminals during every test: k6, watch-metrics, docker stats.
bash scripts/sweep.sh 50 100 200 300 400 500 600 uv run scripts/summarize.py results/lab2/rate-*.json
One laptop, one run. Yours will differ — the shape will not.
S / (1 − ρ)
Capacity = highest rate with p99 inside the target — not the highest throughput ever printed.
db_active = 10
db_pending
200 busy threads, 10 active connections, 190 pending. More Tomcat threads would…?
DB_POOL_SIZE=30 docker compose up -d catalog OUT=results/lab2-pool30 bash scripts/sweep.sh 50 100 200 300 400 500 600
max_connections
K6_WEB_DASHBOARD=true K6_WEB_DASHBOARD_EXPORT=results/lab2-stress.html \ k6 run -e PEAK=600 load/stress.js
Outline: (1) why measure before optimizing; (2) closed vs open models; (3) the scripts; (4) gauges from inside; (5) the sweep and the knee; (6) Little's Law and the pool; (7) moving the bottleneck; (8) stress.