Load Testing Before Launch: What to Test and How to Read It
What to load test before a launch or a campaign, how to script realistic user flows with k6, JMeter or Locust, where it is safe to run the test, and how to read percentiles, errors and the bend in the curve.

A site that works for the ten people checking it says nothing about how it behaves when a thousand arrive after the launch email. Load testing answers three things before real visitors do: how much traffic the system carries before response times climb, which part gives way first, and whether it recovers afterwards without someone restarting it.
The tool is the easy part. The work is deciding what to simulate and reading the result without fooling yourself, early enough that there is still time to fix what the test finds and run it again.
Load testing starts with a traffic number you can defend
A test needs a target, and "as much as possible" is not one. Build the figure from what you already know:
- An existing site: take the busiest hour in your analytics, not the daily average. Note the sessions in that hour and the pages per session.
- A launch or campaign: start from the size of the email list or the ad plan and estimate how many people click in the first few minutes. An enrollment opening or a ticket sale is the extreme case, because nearly everyone arrives in the same minute.
- A margin: agree a multiple of the expected peak with the business. We usually test to about double, so a good day does not become an outage.
Then separate two numbers that get mixed up constantly: concurrent users and requests per second. Someone reading a page is sending no requests at all. Five hundred people who each load a page every twenty seconds produce about 25 page requests per second. Test tools count virtual users with pauses between actions, while your server only feels requests per second.
Script what people do, not one URL
Requesting the home page ten thousand times tests your page cache and little else. Real load is a mix, and the expensive parts are the ones no cache can serve: login, search, cart, checkout, a quiz submission, a dashboard. Take two to four typical paths from your analytics and weight them the way real traffic is weighted: most visitors browse, some search, a few sign in and pay.
Several details separate an honest test from a flattering one:
- sign in as many different test accounts, because one account repeats the same cached rows and can queue behind its own session lock;
- read search terms and product or course ids from a data file, so that every request is not identical;
- put pauses between steps, as a real visitor would;
- fill the test database to production size, because an empty one makes every query look fast;
- point the payment gateway at its sandbox, send email to a catch-all address and stub out CRM or SMS calls. Never send load to a provider's live API without their agreement.
Choose the test shape for what you want to learn
The same script gives different answers depending on how the load is applied over time.
| Test | Load pattern | What it tells you |
|---|---|---|
| Smoke | A handful of users for a minute or two | The script works and nothing is broken before you spend an hour on a long run |
| Average load | Ramp to the expected peak and hold it | Whether a normal busy period stays inside your targets |
| Stress | Climb past the expected peak in steps | Where response times bend and which component fails first |
| Spike | Jump from idle to peak within seconds | Whether caches, connection pools and autoscaling cope with a sudden start |
| Soak | Moderate load held for hours | Memory leaks, disks filling with logs, connections that are never released |
For most launches the order is smoke, average load, then stress. Add a spike test when the event has a fixed start time, and a soak test for a new application with long-running workers.
A small k6 script to adapt
Three open-source tools cover nearly every case. k6 runs scenarios written in JavaScript from the command line. Apache JMeter is a Java application with a graphical editor for building test plans and a command-line mode for running them. Locust describes user behavior in Python. Pick the one whose language your team already reads. The example below is k6.
import http from 'k6/http';
import { check, sleep } from 'k6';
export const options = {
stages: [
{ duration: '5m', target: 100 }, // ramp up to 100 virtual users
{ duration: '15m', target: 100 }, // hold
{ duration: '5m', target: 0 }, // ramp down
],
thresholds: {
http_req_failed: ['rate<0.01'],
http_req_duration: ['p(95)<800'],
},
};
const BASE = 'https://staging.example.com';
export default function () {
const home = http.get(`${BASE}/`);
check(home, { 'home returns 200': (r) => r.status === 200 });
sleep(3);
const catalog = http.get(`${BASE}/courses/`);
check(catalog, { 'catalog returns 200': (r) => r.status === 200 });
sleep(5);
}
Run it with k6 run launch.js. The stages block ramps the number of virtual users, and each one repeats the default function until the test ends. The thresholds block turns the run into a pass or fail: fewer than one request in a hundred may fail, and 95 out of 100 must finish within 800 milliseconds. k6 exits with a non-zero status when a threshold is missed, so the same script can gate a deployment pipeline later. Try it with five users first, then add signed-in steps with http.post in the same way.
Where to run it, and what not to point it at
The best target is a staging environment that matches production: the same server size, the same PHP and database settings, the same caching and CDN setup, and data of production size. A smaller staging server gives numbers you cannot scale up, because half the hardware does not mean half the capacity.
Sometimes production is the only realistic copy. Then treat the test as a planned operation:
- Tell your hosting provider and CDN, and get their agreement. Many treat unannounced load as an attack and will block it or suspend the account, and some plans forbid load tests.
- Pick the quietest hour and tell everyone who works on the site.
- Use test accounts and marked test orders that can be deleted, with payments in sandbox mode and outgoing email off.
- Agree a stop condition in advance, such as an error rate or a response time, and have someone watching the monitoring, ready to stop the run.
- Ramp slowly, and never run a stress or spike test to failure on a site that is serving customers.
Do not load test a shared hosting account, where the neighbors pay for your experiment, or any service you do not own. Check the load generator too. A laptop on office Wi-Fi runs out of CPU or bandwidth long before a server does, so run the test from a cloud machine near your users and watch its CPU.
Reading percentiles, errors and the bend in the curve
The average response time is the least useful number in the report. Percentiles tell the truth: a p95 of 800 milliseconds means 95 out of 100 requests were faster than that, and p99 shows the worst cases. A run with a 300 millisecond average and a p95 of four seconds means one request in twenty was painful.
Read three lines against time together: the number of virtual users, the response time percentiles and the error rate. On a healthy system response time stays flat while users climb. The point where p95 begins to rise faster than the load is the practical capacity of the system. Past it, requests per second stop increasing even though more users are being added, which means something is saturated.
The errors say what that something is:
- 502 or 504 from the web server: PHP workers are exhausted. The PHP-FPM log will say the pool reached
pm.max_children. - "Too many connections": the database connection limit, often because slow queries hold connections open.
- 429 or sudden blocks: your own rate limiter or firewall has spotted the generator. Allow its address for the duration of the test.
- Timeouts on one step only: a lock on a table, or a third-party call that step depends on.
Line those up with server metrics from the same minute: CPU, memory, database connections, the slow query log and queue length. The first resource to reach its ceiling is the bottleneck. Fix that one thing and run the test again, because the next limit is hidden behind it. Our guide to profiling a web application covers finding the cause once you know which component it is.
Finally, watch what happens after the ramp down. Response times should return to normal within a minute or two. If queues stay backed up, the system does not recover unaided, and that matters as much as the peak figure.
Running it yourself or handing it over
A developer who is comfortable scripting, plus a staging environment that mirrors production, is enough to run a useful test in-house.
It is worth getting help when there is no production-like environment and one has to be built, when the result shows capacity below the target and the cause is not obvious, or when the date cannot move, as with a sale on an online store or enrollment day on a learning platform. Our performance optimization team runs the tests, reads them alongside the server metrics and fixes what they expose.
Frequently asked questions
How many virtual users do I need to simulate?
Work backwards from requests per second. Take the page requests per second you expect at peak and multiply by the average pause between a user's actions in your script. If you expect 25 page requests per second and each virtual user pauses 20 seconds between pages, about 500 virtual users produce that load.
Can I load test a WordPress or WooCommerce site?
Yes, with the same care about scenarios. Logged-out pages normally come from a page cache and will look excellent. The cart, checkout, account pages and anything a signed-in user sees bypass that cache and reach PHP and the database, so those are the steps to script.
What response time should I set as the pass mark?
Choose it before the test, per step, and state it as a percentile at the expected peak, for example the p95 for the catalog page and a separate, looser figure for checkout. A target invented after seeing the results is not a target.
Add worldwincoder.com as a preferred source on Google, or open this article in your AI assistant to use it as a source.
