k6 Load Testing (Production-Safe)

How to run read-only, production-safe k6 tests against Mapiry endpoints

Updated April 5, 2026

This doc describes how to run production-safe, read-only load tests with k6. Scripts target GET-only endpoints and require ALLOW_PROD=true to run against live mapiry.com.

Targets (Read-Only)

  • GET / (homepage)
  • GET /health (health check)
  • GET /m/:slug (public map page; default slug: tokyo-coffee)
  • GET /embed/:mapId (public embed; default ID available in code)
  • Optional (with API key): GET /api/v1/maps/:mapId
    • Note: /health is opt-in via INCLUDE_HEALTH=true (it may be restricted in production).

Safety Guardrails

  • Scripts exit unless ALLOW_PROD=true.
  • Only GET requests are generated by default.
  • Start with smoke; ramp slowly while monitoring.

Scripts

The scripts live in scripts/:

  • k6-common.js (shared config/helpers)
  • k6-smoke.js
  • k6-baseline.js
  • k6-stress.js
  • k6-soak.js
  • k6-api-read.js
  • k6-breakpoint.js
  • k6-breakpoint-vus.js
  • run-k6.sh (wrapper for all profiles)

Environment Variables

BASE_URL   (default: https://mapiry.com)
HEALTH_PATH (default: /health)
MAP_SLUG   (default: tokyo-coffee)
EMBED_ID   (default: cm9z8lr9y0001vlybqgshqk79)
API_BASE   (default: ${BASE_URL}/api/v1)
API_KEY    (optional; enables authenticated GET)
MAP_ID     (optional; used with API_KEY)
ALLOW_PROD (required; must be true)
TARGETS    (optional; comma-separated endpoint names: homepage,map_slug,embed,api_get_map,health)
INCLUDE_HEALTH (optional; true to include /health)
RATES      (breakpoint only; comma-separated arrival rates, e.g. 10,20,30)
STEPS      (breakpoint:vus only; comma-separated VU counts, e.g. 10,20,40)
HOLD       (breakpoint profiles; default: 1m)
RAMP       (breakpoint profiles; default: 10s)
PRE_ALLOC  (breakpoint only; override preAllocatedVUs)
MAX_VUS    (breakpoint only; override maxVUs)

Examples

The suites require an explicit ALLOW_PROD=true, so they cannot touch production by accident. Using the wrapper (recommended):

export ALLOW_PROD=true
scripts/run-k6.sh smoke

export BASE_URL=https://mapiry.com
scripts/run-k6.sh baseline -- --out json=./k6-results.json

# API_KEY and MAP_ID are only needed by the `api` suite
export API_KEY=mk_live_xxx
export MAP_ID=abc123
scripts/run-k6.sh stress
scripts/run-k6.sh api

export RATES=10,20,30 HOLD=1m RAMP=15s
scripts/run-k6.sh breakpoint

export STEPS=10,20,40 HOLD=1m RAMP=15s
scripts/run-k6.sh breakpoint:vus

Direct k6 (alternative):

export ALLOW_PROD=true
k6 run scripts/k6-smoke.js
k6 run scripts/k6-baseline.js
k6 run scripts/k6-stress.js
k6 run scripts/k6-soak.js
k6 run scripts/k6-api-read.js
k6 run scripts/k6-breakpoint.js
k6 run scripts/k6-breakpoint-vus.js
k6 run --out json=./k6-results.json scripts/k6-baseline.js

Profile Notes

  • smoke: single-VU sanity check across the configured target set.
  • baseline: conservative ramping-arrival-rate test for normal production probing.
  • stress: higher ramping-arrival-rate test to find degradation under heavier read traffic.
  • soak: constant-arrival-rate run for sustained load over time.
  • api: authenticated read-only API test; requires both API_KEY and MAP_ID.
  • breakpoint: steps through configured arrival rates to find the sustained request-rate limit.
  • breakpoint:vus: steps through configured VU counts to find the sustained concurrency limit.

Troubleshooting Failures

  • Set real public MAP_SLUG and EMBED_ID. Defaults may 404 on production.
  • Keep /health disabled unless you know it’s publicly accessible (INCLUDE_HEALTH=true).
  • Inspect failing endpoints quickly:
    • The suite logs [fail] <name> <status> <url> lines to stderr.
    • Export a JSON summary and inspect metrics per status: ALLOW_PROD=true k6 run --summary-export k6-summary.json scripts/k6-baseline.js
  • Add basic headers (already set by default): a friendly User-Agent and Accept.
  • If you suspect WAF/CDN rate limits: reduce arrival rate and/or spread traffic across distinct endpoints.

Operational Guidance

  1. Announce test window, confirm on-call monitoring.
  2. Run k6-smoke.js; verify 0% failures and healthy p95.
  3. Use k6-baseline.js for 5–10 minutes; then carefully raise arrival rate.
  4. If any threshold breach or alert occurs, stop and analyze.
  5. Prefer off-peak hours for stress or soak tests.

Related