How to Safely Load Test a Small PHP Site
A load test is not about breaking the site. It checks how many concurrent requests (visitors hitting the site at the same moment) it takes before response time starts to wobble. Start on your own machine (locally), not the production server, with small numbers.
Recommended Order
Start with 50 to 200 requests against static files (files served unchanged, like images and CSS) and the root page. If the error rate is 0% and the 95th percentile response time (the 95th request when 100 are sorted fastest first) is stable, raise concurrency gradually. Exclude login and file download areas from public load tests.
Local Test Command
# Ubuntu / Debian: install ApacheBench
sudo apt-get install apache2-utils
# Your own local test server must already be listening on port 8080.
curl -I http://127.0.0.1:8080/
ab -n 50 -c 1 http://127.0.0.1:8080/
ab -n 100 -c 5 http://127.0.0.1:8080/
Metrics to Watch
The 95th percentile matters more than the average response time. Even with a low average, a few requests above two seconds can feel slow to real users. If 5xx errors (response codes meaning the problem is on the server side) appear, check PHP-FPM, Nginx workers, disk IO, and log writing first.
Before running the commands
These commands require no private repository files. Replace 8080 with your test server port. Confirm a 200 response with curl; for a 301 or 302, test the final destination, otherwise you mostly measure redirects. For a name-based virtual host reached through a local IP, you can add -H "Host: your-domain" to ab.
A localhost run excludes the internet path and CDN. The load generator shares CPU with the server and can affect the result. PHP’s built-in development server is not a proxy for production Nginx and PHP-FPM capacity. Begin with a controlled before-and-after comparison.
Reading an example result
The following is an illustrative result, not a measurement of the SameOS server.
Complete requests: 100
Failed requests: 0
Requests per second: 25.00 [#/sec] (mean)
Percentage of the requests served within a certain time (ms)
50% 120
95% 400
100% 800 (longest request)
Here p95 is 400 ms. Higher throughput alone does not establish improvement if p95 or failures also increase. Check Non-2xx responses and server logs as well as Failed requests. A dynamic page can produce length failures even when responses are valid. Only after confirming that behavior should you use ab -l to accept variable response lengths.
Change one variable and compare
- Record the URL, request count and concurrency, then keep a baseline. Distinguish a cold cache from a warm one.
- Change one observed bottleneck, such as a slow query, repeated file reads or page caching.
- Repeat with identical settings and compare p95, errors, CPU and memory. Record static CSS and PHP responses separately to help isolate the affected layer.
- Stop if errors, timeouts or normal-user disruption appear. Return to low load and inspect PHP-FPM queues, application logs and disk activity.