Skip to content

Test plans

A test plan is a YAML file that describes one HTTP request and how aggressively workers should repeat it. The CLI parses the file, expands ${ENV_VAR} placeholders, normalizes auth and json into headers/body, and submits the plan to the control plane.

target_url: http://mock-target/health
protocol: http
ramp_pattern: constant
target_rps: 100
duration_sec: 30

protocol is required in the file format; v0.1 supports http only.

Field Required Description
target_url Yes Full URL workers request. Supports ${ENV_VAR} in the string.
protocol Yes http (v0.1)
target_rps Yes Desired aggregate requests per second across all workers
duration_sec Yes How long the load phase runs (seconds)
ramp_pattern No constant (default), ramp, step, or spike — how RPS changes over time
worker_count No Override autoscaler sizing; see Workers
Field Required Description
method No Defaults to GET. Supports standard methods (GET, POST, PUT, PATCH, DELETE, HEAD, OPTIONS).
headers No Map of header names to values; values support ${ENV_VAR}
body No Raw request body string (max 1 MiB); supports ${ENV_VAR}
json No Arbitrary YAML/JSON structure; serialized to body with Content-Type: application/json
timeout_ms No Per-request timeout (1–300000 ms)
expected_statuses No HTTP status codes counted as success; others increment error_count

Do not set both json and body.

Use the auth block instead of setting Authorization or Cookie manually (conflicts are rejected).

Field Description
type bearer, jwt, session, cookie, or header
token For bearer / jwt — sent as Authorization: Bearer <token>
name Cookie or header name for session / cookie / header
value Cookie or header value

All credential fields support ${ENV_VAR} expansion at parse time (CLI/file only).

auth:
type: bearer
token: ${API_TOKEN}
slo:
p95_ms: 500
error_rate_max: 0.01

Used for reporting and UI hints; enforcement policies may evolve by release.

The autoscaler brain computes:

desired_workers = ceil(target_rps / per_worker_rps)

Default per_worker_rps is 500 in Docker Compose. The scaler then starts that many worker containers (or pods on Kubernetes).

Scenario What to set
Higher total RPS Raise target_rps — workers scale up automatically
Same RPS, more connections Set worker_count explicitly; RPS is split across workers
Generator saturated Lower per_worker_rps in autoscaler config or add capacity (K8s)

Important: target_rps is never “per worker.” target_rps: 40 with worker_count: 4 ≈ 10 RPS per worker.

When you run test-scale run -f plan.yaml, the CLI expands:

  • ${VAR} and $VAR (letter-led names only)
  • Unset variables → clear error: environment variable VAR is not set

Expansion applies to target_url, body, header values, and auth fields. It does not walk arbitrary json trees in v0.1 — put secrets in auth or headers.

ramp_pattern Behavior (high level)
constant Hold target_rps for full duration_sec
ramp Increase load over the duration
step Step changes in RPS
spike Short burst pattern

Exact curves are implemented in the worker load executor; use Grafana during a trial run to validate the shape you need.

target_url: https://api.example.com/v1/search
protocol: http
ramp_pattern: constant
target_rps: 50
duration_sec: 60
method: POST
auth:
type: jwt
token: ${SEARCH_API_JWT}
json:
query: performance
limit: 25
timeout_ms: 3000
expected_statuses: [200]
slo:
p95_ms: 800
error_rate_max: 0.005

Submitted plans are stored in Postgres. The UI and test-scale rerun create new runs from saved definitions. Because auth headers are stored after normalization, treat the control plane database as sensitive.