ManagedQA PartnersSee plans

Tooling · 2026-09-03 · 2 min read

A k6 performance smoke, and what a budget looks like

Growth and Scale run a smoke test under baseline load on every release. It is short, it has a written budget per flow, and it fails on a number, not an impression.

Checklist item PF-01 says: critical flows (a path a user takes that costs money or trust if it breaks: sign-up, checkout, invite, export) within agreed budgets under baseline load. The pass criterion is p95 latency within the written budget per flow and an error rate under 1% of requests in the run. The tool is k6. This post is what those words mean in practice.

Baseline load

Not a load test. A smoke is the traffic you already have, replayed against staging for a few minutes: if your busiest hour is 40 concurrent users, the smoke runs 40 virtual users for five minutes across the critical flows. Its job is to catch a release that made something slow, not to find the ceiling.

A budget

A number per flow, written down before the first run. For a typical SaaS: sign-in under 800 ms at p95, dashboard load under 1.5 s, list endpoints under 500 ms, checkout under 2 s end to end. The numbers come from what the product does today plus what you would accept; the point is that they are written, so a release that goes from 400 ms to 1.4 s on a 500 ms budget fails on a number.

The script

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

export const options = {
  vus: 40,
  duration: "5m",
  thresholds: {
    "http_req_duration{flow:list}": ["p(95)<500"],
    "http_req_duration{flow:dashboard}": ["p(95)<1500"],
    http_req_failed: ["rate<0.01"],
  },
};

export default function () {
  const list = http.get(`${__ENV.BASE}/api/invoices?page=1`, { tags: { flow: "list" } });
  check(list, { "list 200": (r) => r.status === 200 });
  const dash = http.get(`${__ENV.BASE}/dashboard`, { tags: { flow: "dashboard" } });
  check(dash, { "dashboard 200": (r) => r.status === 200 });
}

Thresholds are the budget. k6 exits non-zero when one is missed, which is what makes it a checklist item rather than a report.

What it usually finds

The pattern behind most smoke failures is one query per row: a list page that runs a separate query for each item, fine with 20 rows in development and slow with 2,000 in staging. PF-03 counts queries per request for exactly this. The second most common is an unbounded list endpoint (PF-02) that returns everything because nobody wrote a page size.

Where it runs

In your CI (the pipeline that builds and tests every change before it can be merged or deployed), against staging with a realistic dataset, on every release candidate for Growth and Scale. Starter does not include performance items; the limits table says so.

More in tooling

Start with the audit

5 business days, $1,200, credited to the first month.

Blog · ManagedQA Partners