Load Testing with k6 — Find Bottlenecks Before They Lose You Customers
> cd .. / HUB_EDITORIALE
Sviluppo di siti web

Load Testing with k6 — Find Bottlenecks Before They Lose You Customers

[2026-07-26] Author: Ing. Calogero Bono
> share
Zenithby Meteora Web The operating system for your business. Social, clients, bookings and invoices in one platform. Gyms, barbers, professionals. Discover Zenith Free demo · no card

Your site works fine with one user. With ten it still holds. Then comes Black Friday, a campaign launch, a viral post. And the server goes down. You lost sales, you lost trust. We see it every day: businesses discovering the limits of their infrastructure only when it's too late. Performance tests are not optional. They are what separates a professional website from a gamble.

How does k6 compare to Artillery for load testing?

k6 and Artillery are both open-source load testing tools, but they start from different philosophies. k6 is written in Go, uses JavaScript for scripts, and is designed for CI/CD integration. Artillery is Node.js based, uses YAML/JSON configurations, and is simpler for quick tests. At Meteora Web, we use both. We prefer k6 for realistic user simulations – navigating pages, submitting forms, uploading files. We keep Artillery for quick smoke tests on API endpoints.

Key difference: k6 runs in a single-threaded Go process, consuming fewer resources. Artillery, being Node, can be heavier with many users. To simulate 10,000 users, k6 wins. For a quick route test, Artillery is more immediate.

Practical example: k6 test on a contact form

Here's a k6 script that sends 5 requests per second for 30 seconds to a POST endpoint:

Sponsored Protocol

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

export let options = {
  stages: [
    { duration: '30s', target: 5 },
  ],
};

export default function () {
  let url = 'https://yoursite.com/api/contact';
  let payload = JSON.stringify({ name: 'Test', email: 'test@example.com', message: 'Simulated load' });
  let params = { headers: { 'Content-Type': 'application/json' } };
  let res = http.post(url, payload, params);
  check(res, { 'status 200': (r) => r.status === 200 });
  sleep(1);
}

What it does: each iteration sends a POST, checks status, then waits 1 second. The test linearly scales to 5 iterations per second. Run with k6 run script.js.

Which to choose for performance testing: k6 or Artillery?

It depends. If your site is based on WordPress or a traditional CMS, and you want to test full page loads (HTML, CSS, JS, images), k6 is better because you can write complex scripts with data extraction and cookies. Artillery is better for simple APIs: define a YAML with requests and go.

A real case: a client e-commerce with WooCommerce. Before a promotion launch, we used k6 to simulate 50 users browsing, adding to cart, and checking out. k6 allowed us to handle session cookies and the cart. With Artillery we would have written more manual code. With k6 it was straightforward.

Sponsored Protocol

If you need to test an isolated microservice (e.g. login API), Artillery is faster to set up. Here's an Artillery example:

config:
  target: 'https://api.yourservice.com'
  phases:
    - duration: 60
      arrivalRate: 10
scenarios:
  - flow:
    - post:
        url: '/login'
        json:
          username: 'test'
          password: 'test'
        capture:
          - json: '$.token'
            as: 'token'

Run with artillery run test.yml. Simple, right?

How to write a k6 load test that simulates real users?

A common mistake: testing only the endpoint, not the user flow. A real user arrives from the homepage, clicks, searches, fills forms. You should replicate that. k6 allows you to create scripts with multiple steps, extract data from responses, and use them in subsequent requests. Here's a simplified purchase flow example:

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

export default function () {
  // 1. Homepage
  let home = http.get('https://yourstore.com/');
  check(home, { 'homepage OK': (r) => r.status === 200 });
  sleep(2);

  // 2. Search for a product
  let search = http.get('https://yourstore.com/?s=shirt');
  check(search, { 'search OK': (r) => r.status === 200 });
  sleep(1);

  // 3. Add to cart
  let addCart = http.post('https://yourstore.com/cart', {
    product_id: 123,
    quantity: 1
  });
  check(addCart, { 'added to cart': (r) => r.status === 200 });
  sleep(1);

  // 4. Checkout page
  let checkout = http.get('https://yourstore.com/checkout/');
  check(checkout, { 'checkout OK': (r) => r.status === 200 });
  sleep(1);
}

Note: we used sleep() to simulate reading time. You can vary times with random to mimic human behavior. k6 also has the k6/execution module for data like VU ID.

Sponsored Protocol

How to interpret load test results?

Two key metrics: response time (95th percentile) and error rate. If the 95th percentile exceeds 2 seconds for a page, you need to optimize. If there are 5xx errors, the server cannot handle it. k6 produces detailed output. We always look at the http_req_duration chart.

Sponsored Protocol

A practical tip: test under normal load and under stress. Normal load: 10-20 concurrent users for a medium site. Stress: double until you see degradation. Note the breaking point.

Example k6 output:

http_req_duration..............: avg=1.2s  min=0.3s  med=1.1s  max=4.5s  90% 2.1s  95% 2.8s
http_req_failed................: 2.00%  ✓ 80  ✗ 3920

Here the 95% responds within 2.8 seconds — acceptable for an API, but for a webpage we'd want under 2 seconds. The 2% error rate is too high; you need to investigate.

How to integrate k6 into your CI/CD pipeline?

Running performance tests on every deploy is the best way to avoid regressions. k6 integrates with GitHub Actions, GitLab CI, Jenkins. At Meteora Web, we do this for every project we release. Here's an example GitHub Actions workflow:

name: Load test
on: [push]
jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
      - name: Run k6 test
        uses: grafana/k6-action@v0.3.0
        with:
          filename: tests/load.js
          flags: --vus 10 --duration 30s 

Important: in your CI environment, do not test the production server! Use a staging environment. And set thresholds to fail the pipeline if performance degrades.

Sponsored Protocol

Common mistakes to avoid in performance testing

1. Testing only locally. Local network has zero latency. You must test on a remote server or an environment that simulates your users' distance.

2. Forgetting the database. Many tests ignore queries. If your site does 100 queries per page, under load the database collapses. Use tools like k6/x/dbi or monitor DB load.

3. Not testing static resources. k6 can also simulate loading images and CSS using k6/browser (browser mode). For more realistic tests, use the k6 browser module.

4. Ignoring system limits. Open ports, file handles, network connections. Make sure your OS allows enough simultaneous connections.

What to do next

  1. Install k6 on your local machine: brew install k6 (Mac), choco install k6 (Windows), or download the binary from k6.io.
  2. Write a simple test for your homepage. Run with 10 users for 30 seconds. Look at response times.
  3. Set thresholds in your test: e.g., thresholds: { http_req_duration: ['p(95)<2000'] }. This fails the test if the 95th percentile exceeds 2 seconds.
  4. Integrate the test into your deploy with GitHub Actions or GitLab CI. Make it fail before code reaches production.
  5. Read the official documentation: k6 docs and Artillery docs. We consult them daily.

Don't wait for a bottleneck to cost you a customer. Start today.

For a deeper dive into the entire testing process, read our pillar guide: Software Testing Pyramid, Automation, and Strategies for Code That Doesn't Keep You Awake (link placeholder – adjust if needed).

> share
Ing. Calogero Bono

> AUTHOR_EXTRACTED

Ing. Calogero Bono

Ingegnere informatico, fondatore di Meteora Web e Zenith OS. System administrator e progettista di piattaforme, app e CMS proprietari, con esperienza in sviluppo full-stack, marketing digitale ed ecosistema Google.
[ Read Full Dossier ]

> METEORA_WEB // DIGITAL AGENCY

We build the digital presence your business deserves.

Websites, social media, online advertising, e-commerce and high-performance hosting, engineered with method by computer engineers in Sciacca, for all of Italy.

> MW_JOURNAL

> READ_ALL()