Load Test Bootstrap
Most NFR audits ask "is there a performance budget test?" and then move
on without one existing. This skill actually builds and runs a small,
bounded load test — the thing that would catch a database connection pool
exhausting at 50 concurrent users, or a serverless function's cold-start
tax showing up only under real concurrency, neither of which Lighthouse
can ever find (it tests one page load, alone, once).
Works against any HTTP target: a static site's CDN edge, a backend API,
a serverless function endpoint — k6 and Artillery are both just HTTP load
generators underneath.
When not to use this
- Single-user page-load performance (LCP, TBT, bundle size) →
Lighthouse /
nfr-gap-audit's baseline, or production-cwv-review for
real-world field data. This skill measures throughput and latency under
concurrency, not single-load render performance.
- Production, without the user's explicit go-ahead on target and
intensity — never assume authorization. Real load against a live site
is not a read-only audit action; treat it with the same care as any
other action with real external effect.
- A one-off "is the site up" check → that's a health check, not a
load test; way overkill for the question being asked.
Phase 0 — Scope & consent (never skip)
Before writing or running anything, confirm explicitly with the user:
- Target: which 2-5 endpoints (homepage, one form POST, one API
route) — critical paths, not everything.
- Environment: staging/preview URL strongly preferred; production
only with explicit, informed agreement to a bounded intensity.
- Intensity: a conservative default proposal — e.g. ramp 0→20
virtual users over 30s, hold 1 minute, ramp down over 15s — and let
the user raise or lower it. Never default to an aggressive profile
against a target you don't control the infrastructure cost of.
- Timing: avoid peak traffic hours if testing production; ask if
there's a known low-traffic window.
If the user hasn't given clear, specific answers to all four, stop and
ask — this is the one phase in this skill (and arguably in this whole
audit family) where proceeding on an assumption is a real-world mistake,
not just a wasted review cycle.
Phase 1 — Scaffold
Write a k6 script (load-test.js, saved locally — not committed unless
the user wants it kept as a repeatable asset) with:
- The agreed ramp profile (
stages in k6's options)
- One scenario per agreed endpoint
- Thresholds that make the run pass/fail objectively:
http_req_duration: ['p(95)<800'], http_req_failed: ['rate<0.01']
(adjust the numbers to the site's own stated performance targets if it
has any, e.g. this project's Lighthouse total-blocking-time budget)
Artillery is a reasonable alternative if the project already uses it or
the user prefers YAML config over k6's JS.
Phase 2 — Run
Execute against the agreed target at the agreed intensity.
- If k6/Artillery isn't installed locally, ask before installing (per the
project's own "ask before installing tools" convention) — a Docker
fallback (
docker run --rm -i grafana/k6 run - <load-test.js) avoids a
local install entirely if Docker is already available.
- Watch the run live if possible; abort immediately if error rates spike
well beyond the threshold or the target shows signs of real distress
(this is production-adjacent risk management, not just test hygiene).
Phase 3 — Findings
Report per endpoint: p50/p95/p99 latency, error rate, and — if the ramp
was steep enough to find it — the approximate VU count where the target
started degrading (rising error rate or latency knee). Compare against
the thresholds set in Phase 1 and call out any that failed.
Do not extrapolate beyond what was actually run — "held up fine to 20 VUs
over 1 minute" is the honest scope of the finding, not "the site can
handle production traffic."
1---2name: load-test-bootstrap3description: Scaffolds and runs a minimal, real load/stress test (k6 by default, Artillery as an alternative) against a site's or API's critical endpoints — the "performance budget test" that NFR checklists ask for but that a Lighthouse-only audit never actually exercises, since Lighthouse simulates exactly one user. Works on any HTTP-reachable site or API, static-front or backend. Trigger on "load test this", "how does this hold up under traffic", "stress test the API", "set up performance budget tests", or when an NFR audit flags load-testing as unverified. NOT for browser-rendering performance (Lighthouse/CWV — use nfr-gap-audit's baseline or production-cwv-review). NOT something to run against production without explicit, scoped authorization — generating real load against a live site has real cost and risk (rate limits, real infra bills, false alerts, genuine degradation for real visitors); always confirm target, intensity, and time window with the user first, and prefer a staging environment when one exists.4---56# Load Test Bootstrap78Most NFR audits ask "is there a performance budget test?" and then move9on without one existing. This skill actually builds and runs a small,10bounded load test — the thing that would catch a database connection pool11exhausting at 50 concurrent users, or a serverless function's cold-start12tax showing up only under real concurrency, neither of which Lighthouse13can ever find (it tests one page load, alone, once).1415Works against any HTTP target: a static site's CDN edge, a backend API,16a serverless function endpoint — k6 and Artillery are both just HTTP load17generators underneath.1819## When not to use this2021- **Single-user page-load performance** (LCP, TBT, bundle size) →22 Lighthouse / `nfr-gap-audit`'s baseline, or `production-cwv-review` for23 real-world field data. This skill measures throughput and latency under24 concurrency, not single-load render performance.25- **Production, without the user's explicit go-ahead on target and26 intensity** — never assume authorization. Real load against a live site27 is not a read-only audit action; treat it with the same care as any28 other action with real external effect.29- **A one-off "is the site up" check** → that's a health check, not a30 load test; way overkill for the question being asked.3132## Phase 0 — Scope & consent (never skip)3334Before writing or running anything, confirm explicitly with the user:351. **Target**: which 2-5 endpoints (homepage, one form POST, one API36 route) — critical paths, not everything.372. **Environment**: staging/preview URL strongly preferred; production38 only with explicit, informed agreement to a bounded intensity.393. **Intensity**: a conservative default proposal — e.g. ramp 0→2040 virtual users over 30s, hold 1 minute, ramp down over 15s — and let41 the user raise or lower it. Never default to an aggressive profile42 against a target you don't control the infrastructure cost of.434. **Timing**: avoid peak traffic hours if testing production; ask if44 there's a known low-traffic window.4546If the user hasn't given clear, specific answers to all four, stop and47ask — this is the one phase in this skill (and arguably in this whole48audit family) where proceeding on an assumption is a real-world mistake,49not just a wasted review cycle.5051## Phase 1 — Scaffold5253Write a k6 script (`load-test.js`, saved locally — not committed unless54the user wants it kept as a repeatable asset) with:55- The agreed ramp profile (`stages` in k6's `options`)56- One scenario per agreed endpoint57- Thresholds that make the run pass/fail objectively:58 `http_req_duration: ['p(95)<800']`, `http_req_failed: ['rate<0.01']`59 (adjust the numbers to the site's own stated performance targets if it60 has any, e.g. this project's Lighthouse `total-blocking-time` budget)6162Artillery is a reasonable alternative if the project already uses it or63the user prefers YAML config over k6's JS.6465## Phase 2 — Run6667Execute against the agreed target at the agreed intensity.68- If k6/Artillery isn't installed locally, ask before installing (per the69 project's own "ask before installing tools" convention) — a Docker70 fallback (`docker run --rm -i grafana/k6 run - <load-test.js`) avoids a71 local install entirely if Docker is already available.72- Watch the run live if possible; abort immediately if error rates spike73 well beyond the threshold or the target shows signs of real distress74 (this is production-adjacent risk management, not just test hygiene).7576## Phase 3 — Findings7778Report per endpoint: p50/p95/p99 latency, error rate, and — if the ramp79was steep enough to find it — the approximate VU count where the target80started degrading (rising error rate or latency knee). Compare against81the thresholds set in Phase 1 and call out any that failed.8283Do not extrapolate beyond what was actually run — "held up fine to 20 VUs84over 1 minute" is the honest scope of the finding, not "the site can85handle production traffic."