Skip to main content

Load Testing

Load testing answers a different question than Lighthouse: what happens when many users arrive at once?

What You Learn

  • Whether caching behaves as expected under concurrency.
  • Which layer fails first (CDN, web server, PHP workers, database).
  • What "safe" capacity looks like for your real routes.

Test Types

TypeWhat it isWhen to run it
Smokesmall load to validate toolingbefore every real run
Loadexpected concurrency for 10+ minutesafter major optimizations
Stressramp until you see failure modeswhen sizing infrastructure
Spikesudden burstwhen you expect campaign traffic
Soaksteady load for a long timewhen you suspect leaks or degradation

Tooling

Good defaults:

  • k6 for scripted scenarios.
  • ab for quick sanity checks.
  • A paid external provider when you need geographically distributed load.

Run a Basic Test

caution

Do not run uncached stress tests against production unless you fully understand the risk. Use staging for origin-capacity tests.

Quick cached homepage test (ab)
ab -n 500 -c 50 https://example.com/
k6-sample-scenario.js
import http from 'k6/http';
import { check, sleep } from 'k6';

export const options = {
stages: [
{ duration: '1m', target: 10 },
{ duration: '3m', target: 25 },
{ duration: '1m', target: 0 },
],
};

export default function () {
const pages = [
'https://example.com/',
'https://example.com/some-post/',
'https://example.com/?s=test',
];

const url = pages[Math.floor(Math.random() * pages.length)];
const res = http.get(url);

check(res, { 'status is 200': (r) => r.status === 200 });
sleep(1);
}

Before You Test

  • Make sure your test traffic will not trigger WAF/rate limits (or whitelist the test source).
  • Monitor the origin during the run (CPU/RAM/disk, PHP workers, DB).
  • Test from outside the origin network so latency is realistic.

Test Scenarios for WordPress

ScenarioWhat to TestConfiguring the Test
Homepage (cached)CDN + server cache effectivenessSimple GET to homepage
Blog post (cached)Content page deliveryGET to a published post
SearchDynamic (uncacheable) requestGET /?s=test
WooCommerce productDynamic with cart/sessionGET product page
Contact form submissionPOST handling under loadPOST to form endpoint
WP Admin loginAuthentication under loadPOST to /wp-login.php

Interpreting Results

Focus on these signals:

  • Tail latency grows fast while median stays OK: you are saturating something.
  • Errors appear (429/5xx): you hit rate limits or worker limits.
  • Throughput plateaus while latency climbs: the bottleneck is reached.

Common bottleneck hints:

SymptomLikely bottleneckNext step
response time rises on uncached URLsPHP/DB workprofile slow routes; reduce dynamic work
5xx under concurrencyworker saturationreview PHP-FPM/LSAPI workers and queues
cache HIT collapses under testcache bypass/misconfigverify cookies, query strings, and cache rules

Common Mistakes

MistakeWhat HappensHow to Fix
Testing from the same serverNetwork latency is 0, results are unrealisticTest from a different machine or cloud
Testing only the homepageMiss slow dynamic pagesInclude search, login, and product pages
Running too few requestsStatistical noise dominates resultsRun at least 500 requests per scenario
Ignoring server-side metricsCannot identify the bottleneckMonitor CPU, RAM, and PHP workers during test
Testing without cacheUnrealistic results (production uses cache)Test with cache enabled for real-world data
Ignoring error rateHigh throughput but 10% errors looks "fast"Always check error rate alongside speed

Checklist

  • Scenarios include at least one cached page and one uncached/dynamic route.
  • Origin monitoring runs during the test.
  • Test source is not blocked or rate-limited.
  • Results and the exact test configuration are saved.

What's Next