Why load test

Performance issues discovered in production affect real users. A 30-minute load test before launch catches capacity limits, memory leaks, connection pool exhaustion, and slow queries under concurrency.

k6 basics

import http from "k6/http";
import { check, sleep } from "k6";

export const options = {
  stages: [
    { duration: "2m", target: 50 },   // ramp up
    { duration: "5m", target: 50 },   // steady state
    { duration: "2m", target: 0 },    // ramp down
  ],
  thresholds: {
    http_req_duration: ["p95 < 300"],  // fail if P95 > 300ms
    http_req_failed:   ["rate < 0.01"], // fail if error rate > 1%
  },
};

export default function () {
  const res = http.get("https://api.example.com/orders");
  check(res, { "status 200": (r) => r.status === 200 });
  sleep(1);
}

What to watch during the test

  • P95/P99 latency — not average. Average hides tail latency problems.
  • Error rate — should be near zero under expected load.
  • DB connection pool — pool exhaustion shows up as latency spikes at a threshold concurrency.
  • Memory — watch for growth that does not plateau (memory leak).