84 lines
1.6 KiB
Markdown
84 lines
1.6 KiB
Markdown
# k6 Load Testing
|
|
|
|
Reproducible load test profile for `POST /api/v1/decide`.
|
|
|
|
## Prerequisites
|
|
|
|
- Docker + Docker Compose
|
|
- `jq`
|
|
- Running stack (`docker compose -f compose.yaml up -d`)
|
|
|
|
## One-command run
|
|
|
|
```bash
|
|
./infrastructure/k6/run-decide.sh
|
|
```
|
|
|
|
This command:
|
|
|
|
1. Prepares deterministic fixture via `prepare_k6_fixture`.
|
|
2. Runs `grafana/k6` in a pinned container image.
|
|
3. Saves artifacts to `artifacts/k6/<RUN_ID>/`.
|
|
|
|
Artifacts:
|
|
|
|
- `fixture.json`
|
|
- `run.env`
|
|
- `summary.json`
|
|
|
|
## Reproducible rerun
|
|
|
|
Use the same `RUN_ID` and k6 profile parameters.
|
|
|
|
```bash
|
|
RUN_ID=baseline_20260224 \
|
|
START_RPS=20 \
|
|
RAMP_UP_RPS=200 \
|
|
HOLD_RPS=200 \
|
|
HOLD_DURATION=2m \
|
|
./infrastructure/k6/run-decide.sh
|
|
```
|
|
|
|
## Target URL
|
|
|
|
Default target for k6 container:
|
|
|
|
- `K6_BASE_URL=http://host.docker.internal`
|
|
|
|
Override if needed:
|
|
|
|
```bash
|
|
K6_BASE_URL=http://host.docker.internal:14609 ./infrastructure/k6/run-decide.sh
|
|
```
|
|
|
|
## Profile knobs
|
|
|
|
- `START_RPS`
|
|
- `RAMP_UP_RPS`
|
|
- `HOLD_RPS`
|
|
- `RAMP_UP_DURATION`
|
|
- `HOLD_DURATION`
|
|
- `RAMP_DOWN_DURATION`
|
|
- `PRE_ALLOCATED_VUS`
|
|
- `MAX_VUS`
|
|
- `THRESHOLD_ERROR_RATE`
|
|
- `THRESHOLD_P95_MS`
|
|
- `THRESHOLD_P99_MS`
|
|
- `K6_IMAGE`
|
|
|
|
## Compare two runs
|
|
|
|
```bash
|
|
BASE=artifacts/k6/baseline_20260224/summary.json
|
|
CAND=artifacts/k6/candidate_20260224/summary.json
|
|
|
|
jq -n --argfile b "$BASE" --argfile c "$CAND" '{
|
|
baseline_p95_ms: $b.metrics.http_req_duration["p(95)"],
|
|
candidate_p95_ms: $c.metrics.http_req_duration["p(95)"],
|
|
baseline_req_per_s: $b.metrics.http_reqs.rate,
|
|
candidate_req_per_s: $c.metrics.http_reqs.rate,
|
|
baseline_error_rate: $b.metrics.http_req_failed.value,
|
|
candidate_error_rate: $c.metrics.http_req_failed.value
|
|
}'
|
|
```
|