All articles
Performance

Performance Testing Strategies That Work

A practical guide to load and performance testing with k6, JMeter, and Lighthouse—plus how to track Core Web Vitals and integrate it all into your CI/CD pipeline.

CCCris Carlo DapitanonSr. QA Automation Engineer
3 min read

Functional tests tell you whether a feature works. Performance tests tell you whether it still works when real users show up. Too often, performance testing happens once before a big launch—if at all. The strategies below make it a continuous, routine part of delivery.

Know which question you are asking

Different performance tests answer different questions. Pick the type before you pick the tool.

  • Load test — Does the system meet its targets under expected traffic?
  • Stress test — Where does it break, and does it fail gracefully?
  • Spike test — Can it absorb sudden bursts, like a marketing email or a viral post?
  • Soak test — Does performance degrade over hours (memory leaks, connection exhaustion)?
  • Front-end performance — How fast does the page feel to a real user on a real device?

Choosing the right tool

k6 — code-first load testing

k6 scripts are written in JavaScript, live in the same repository as your code, and run cleanly in CI. Thresholds turn performance goals into pass/fail criteria, so a slow build fails just like a broken one.

load-test.js
import http from "k6/http";
import { check, sleep } from "k6";

export const options = {
  stages: [
    { duration: "2m", target: 50 },  // ramp up to 50 virtual users
    { duration: "5m", target: 50 },  // hold steady load
    { duration: "1m", target: 0 },   // ramp down
  ],
  thresholds: {
    http_req_failed: ["rate<0.01"],    // less than 1% errors
    http_req_duration: ["p(95)<800"],  // 95% of requests under 800ms
  },
};

export default function () {
  const res = http.get(`${__ENV.BASE_URL}/library`);
  check(res, { "status is 200": (r) => r.status === 200 });
  sleep(1);
}

Run it with k6 run -e BASE_URL=https://staging.example.com load-test.js. If a threshold is breached, k6 exits with a non-zero code and the pipeline fails.

JMeter — protocol breadth and complex scenarios

JMeter shines when you need many protocols, complex correlation, or a GUI to design test plans with stakeholders. Design in the GUI, but always execute in non-GUI mode for accurate results:

bash
jmeter -n -t checkout-plan.jmx -l results.jtl -e -o report/

Lighthouse — what users actually experience

Back-end speed is only half the story. Lighthouse audits front-end performance and reports Google's Core Web Vitals, the metrics that reflect real user experience:

  • Largest Contentful Paint (LCP) — loading speed. Good: 2.5 seconds or less.
  • Interaction to Next Paint (INP) — responsiveness. Good: 200 milliseconds or less.
  • Cumulative Layout Shift (CLS) — visual stability. Good: 0.1 or less.

Lighthouse CI can enforce budgets on every build:

lighthouserc.json
{
  "ci": {
    "collect": {
      "url": ["https://staging.example.com/"],
      "numberOfRuns": 3
    },
    "assert": {
      "assertions": {
        "categories:performance": ["error", { "minScore": 0.9 }],
        "largest-contentful-paint": ["error", { "maxNumericValue": 2500 }],
        "cumulative-layout-shift": ["error", { "maxNumericValue": 0.1 }],
        "total-blocking-time": ["warn", { "maxNumericValue": 200 }]
      }
    }
  }
}

Read the results like an engineer

  • Use percentiles, not averages. An average of 300ms can hide a p99 of 5 seconds—and those slow requests are the ones users remember.
  • Establish a baseline. A number means little until you can compare it to the last release.
  • Correlate with server metrics. CPU, memory, database connections, and slow queries explain why latency rose.
  • Test in a production-like environment. Results from an undersized staging server can mislead in either direction.

Make performance testing continuous

  1. 1Run Lighthouse CI on every pull request for key pages.
  2. 2Run a short k6 smoke load test on every deployment to staging.
  3. 3Schedule full load, stress, and soak tests nightly or weekly.
  4. 4Alert the team automatically when thresholds are breached.
Performance is a feature. Test it like one—continuously, with clear thresholds, and with results everyone can see.
CC

Written by Cris Carlo Dapitanon

Sr. QA Automation Engineer specializing in Playwright and Cypress automation, performance testing, CI/CD pipelines, and AI-powered testing.

More articles

View all