Skip to content

Let visitors choose a test's shape, rate, duration and request mix - #4

Merged
rshdhere merged 3 commits into
mainfrom
feat/visitor-test-options
Oct 5, 2026
Merged

rshdhere merged 3 commits into
mainfrom
feat/visitor-test-options

Conversation

@rshdhere

@rshdhere rshdhere commented Oct 5, 2026

Copy link
Copy Markdown
Owner

Why

Every visitor test was 500 req/s for 30 s (15,000 requests), fixed in .env. Visitors could not explore how a server behaves under more load, a ramp, a spike, or a different request mix.

What visitors can pick now

On both the single-server page and Head to head, from fixed menus:

Setting Choices
Shape Steady · Ramp (climb to the peak, to see where latency bends) · Spike (calm, sudden burst, calm)
Peak rate per server 100 · 250 · 500 · 1000 · 2000 req/s (RUNNER_RATES)
Duration 15 s · 30 s · 60 s (RUNNER_DURATIONS)
Requests Mostly reads · Write-heavy · Health checks only

The page shows a live estimate ("About 45,000 requests in total, 15,000 to each server") and greys out rates that would break the budget for the number of servers picked.

Validation and safety

  • The runner accepts only exact menu values; anything else is a 400 with a plain message, counted as an invalid-settings rejection. k6 checks the settings again (bench/k6/src/settings.ts).
  • A test may send at most RUNNER_MAX_TOTAL_RATE req/s across all its servers (default 2000). Measured locally: generating 3000 req/s took k6 about 1.9 CPU cores, which on the 2-core VPS would starve the servers and the other sites for the whole test.
  • The runner container (where k6 runs) is capped at 768 MB; k6's virtual users are sized from the rate and capped so big tests fit. At the heaviest test k6 used 161 MiB.
  • Cooldown, one-test-at-a-time and the per-visitor hourly limit are unchanged.

Dashboards

Every metric is tagged with shape, mix and rate; Run Comparison shows them as columns; test ids read like express-ramp-1000rps-web-<time>; the leaderboard's fixed-rate p99 only counts steady, mostly-reads runs.

Tested locally (full stack)

  • Validation: off-menu shape, rate, duration and mix, a rate=500;rm -rf injection and an over-budget race are all refused.
  • Shapes: steady holds the rate; ramp climbs 66 → 993 req/s; spike runs 40 → 200 → 40 and fits its duration exactly.
  • A 3-way race at 1000 req/s each: 90,000 requests, 0 failures, 3 dropped iterations; typical p99 Go 3.1 ms, Express 22.1 ms, FastAPI 48.2 ms.

Breaking change

RUNNER_SCRIPT and RUNNER_MATCH_RATE are no longer read. RUNNER_RATE and RUNNER_DURATION now only preselect a menu value. The VPS's infra/.env keeps working; the old keys are ignored.

- Add bench/k6/src/settings.ts: read and validate RATE, DURATION, SHAPE (steady, ramp, spike) and MIX (reads, writes, health), and build the arrival-rate scenario
- Fit every shape exactly in its duration, including the spike's two 2s jumps
- Size k6 virtual users from the rate and cap them (300 per server), so big tests fit the runner's memory limit
- Turn the request mix into named mixes in workload.ts: mostly reads, write-heavy, and health checks only
- Tag every metric with shape, mix and rate, and record shape and mix in run summaries
- Document the settings in bench/README.md
- Add a settings menu to the single-test and head-to-head pages: shape, peak rate, duration and request mix, with a live request estimate
- Accept only exact menu values (infra/runner/settings.go) and refuse tests over RUNNER_MAX_TOTAL_RATE across all servers, counted as invalid-settings rejections
- Pass the settings to k6, the trace span, the logs and the test id (e.g. express-ramp-1000rps-web-<time>)
- Poll for a free runner on both forms instead of reloading, so a visitor's choices survive
- Replace RUNNER_SCRIPT and RUNNER_MATCH_RATE with RUNNER_RATES, RUNNER_DURATIONS and RUNNER_MAX_TOTAL_RATE (default 2000)
- Cap the runner container, where k6 runs, at 768 MB

BREAKING CHANGE: RUNNER_SCRIPT and RUNNER_MATCH_RATE are no longer read; visitors choose the shape and every server in a test gets the same rate. RUNNER_RATE and RUNNER_DURATION now only preselect a menu value.
- Add shape, mix and peak-rate columns to Run Comparison
- Limit the leaderboard's fixed-rate p99 to steady, mostly-reads runs so it stays like for like
- Rewrite the test-conditions note for visitor-chosen settings
- Document the visitor menus, the total-rate budget and the runner memory cap in infra/README.md
@rshdhere
rshdhere merged commit 258b35f into main Oct 5, 2026
16 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant