In this guide 6 sections
Build the test from your own busiest day, not from a round number of users, and pull the access log to list the journeys people followed. Copy the ramp, agree the pass mark before the run and watch the database during it, then rehearse weeks ahead of the event.
Start from last year’s busiest hour
Open the web server access log for your worst day, whether that was result day, a flash sale or the last working day of the month. Find the single busiest hour. Count requests per minute inside it. Record the 95th percentile response time as your baseline for that hour, since every later run is compared with it.
Then split those requests by URL and by method, because a few pages take most of the traffic and the login page alone may carry a large share. Your test must reproduce that mix. Even spreads tell you nothing.
No log from last year? Use the analytics export and the order table instead, where orders per minute is a rough stand-in that you should write down plainly as a guess.
- Requests per minute at the peak and at the start of the hour
- Top ten URLs by hits, with their share of the total
- Share of requests that were logged in and share that were anonymous
- Share of requests that wrote a row, such as a booking or an order
Script the journeys real users followed
Hitting the home page proves nothing. Real traffic is messier. Real users log in, search a catalogue, open a record, fill a long form and pay by card, and each of those steps touches different tables.
Write one script per journey in k6, JMeter or Locust, and give each script its own pool of test accounts with think time between clicks. Two virtual users must never edit the same cart, the same seat or the same appointment slot, or the test measures lock fights instead of capacity.
Set the mix from the log. A results portal is almost all reads. A ticketing system on release day is mostly writes, and it is writes that lock rows and queue behind each other at the database.
Copy the ramp, then add a spike
Busy days rarely start at full speed. Traffic may climb for an hour, or it may jump within ninety seconds once a campaign message lands on thousands of phones at the same moment. These are two different tests.
Run the slow climb first. Note where the system starts to bend. Then run the jump, which hits connection pools, cold caches and background workers that have not yet started, and which breaks things a gentle ramp never touches.
Add a margin above last year’s peak. Ask the business how much bigger this year’s event will be, from a campaign to a larger intake, and use that number even if it is a guess.
- A steady climb to the peak over the same hour as the real day
- A sudden jump for the minute after a campaign message
- A hold at peak for at least thirty minutes
- A slow drop, to see whether memory is ever released
Agree the pass mark before the first run
Write the pass mark on one line. Do it before anyone sees a graph. For example, ninety-five of every hundred checkout requests finish within three seconds and fewer than one in a hundred returns an error.
Without a written mark, every result gets argued, because the people who built the test want a pass and the people who hold the budget want a fail. A number fixed in advance ends the debate.
Put a name beside each limit. When a limit is missed, that person decides whether to fix it before the event or accept the risk in writing, and no committee gets to dilute it.
Watch the database, not only the website
Response times say that something is slow. They never say where. The database usually knows. During the run, keep a second screen on the database showing active connections, lock waits, the slow query log, replica lag and the disk queue.
Watch the app servers for CPU and memory too, plus any queue of background jobs such as email sending, report builds and payment callbacks. A queue that grows during the hold and never shrinks means work arrives faster than it leaves, and on the real day users feel that backlog.
Rehearse at least three weeks ahead. That leaves time to add an index, raise a pool size or move a nightly export out of the busy window. Rerun the script and compare graphs.
- Connections in use against the pool limit
- Queries running longer than one second
- Rows locked and the longest wait
- Free disk and write latency on the data volume
Load test plan sheet
Four blocks share one printed page. Traffic holds requests per minute, the top ten URLs and the read to write split, while journeys list one row per script with its account pool. The pass mark block names each limit with its number and its owner, and the run log records date, ramp type, result and the fix made afterwards.
Open a blank worksheet to printQuestions owners ask
How many virtual users do I need?
Start from requests per minute in your busiest hour, then convert that rate into users using the time a real person spends between clicks. Then add this year’s expected margin.
Can I run a load test on the live system?
Avoid it. Test on a copy that holds production-sized data. A small database hides slow queries, so the copy needs the same row counts, even if the hardware is a little smaller.
What should I do about payment gateways and SMS providers?
Point the test at their sandbox. Or replace each one with a stub that waits a realistic time, because real calls are billed and may get your account flagged. Check the provider’s own rate limits separately.
How often should we repeat the test?
Repeat it before every event that matters and after any large release, such as a new payment flow or a database upgrade. Keep the scripts beside the code, so each run reuses the same journeys, and compare the graphs from run to run against the same pass mark.
