We recently transferred over a resource-intensive site to the FireupWP stack and figured we would run a simple brute-force performance test. We wanted to to see at what level of traffic we could make the site fail.
The site itself has 16,000+ registered users and quite a number of heavy duty plugins for things such as e-Commerce, forums, content restriction, support, forms, email marketing, security and documentation.
It is hosted on a 2-core (dedicated) Linode VM and proxied using CloudFlare. Additionally, it uses WPRocket for its page cache and Redis for its object cache.
The Linode VM cost is $30.00/month. So, relatively low-priced considering all the complex functionality embedded in the site!
Initial Test: 50 Virtual Users
For this test, we figured we’d run a bunch of traffic to the three most commonly visited pages: The home page, the features page and the add-ons page.
We configured the test to ramp up to 50 virtual users who would then hammer the server with little pause for 5 minutes.
We used https://k6.io/ as the load testing service.
As you can see from the image above, there were no missed requests and, at the peak, the load-tester sent over 143 requests per minute. The colored lines show the following pieces of test data:
- Green: Number of virtual nusers
- Purple: Number of requests
- Blue: Response time
In the real world, hammering the server with 50 concurrent users with no let-up is the equivalent of at least a couple of hundred real users making requests to the server, pausing to read the response and then making another request.
100 Virtual Users
Since the server didn’t fall over at 50 users, we decided to try 100 virtual users. At this level, the two CPUs definitely red-lined!
Still, not a single request was dropped:
However, we could start to see an increase in the time it took for requests to be processed.
The green line in the image above shows the response time for requests – you can see that there were times where the response times started to really spike on occasion (lower is better, higher is worse).
100 virtual users hammering at the server non-stop is the equivalent of at least four hundred real world users navigating the site normally.
200 Virtual Users
At this level we fully expected the server to either crash or have very lengthy response times. The server didn’t crash but the response times became much higher. In fact, the average response time was 10 times as high as the baseline 50 user test. Ouch. But, hey, what do you expect out of a $30.00 per month server?
For the first time, we got some 502 errors:
I think it’s safe to say that the limits of the server and it’s cloud-flare proxy is somewhere between 100 and 200 virtual users hammering at it non-stop. Or somewhere between 400 and 800 real-world users accessing cacheable pages.
Based on the results of these tests it’s clear that the bottle-neck is CPU. Both cores were red-lined at 100% for almost the entire duration of the 100 VU and 200 VU tests.
If we really needed to, we could just scale the server up to add CPUs as necessary to handle the load until something else becomes the bottle-neck.
But what happens if the pages aren’t cacheable? What are the server limits then? Most WordPress sites primarily serve cacheable pages with a few non-cacheable pages. Only users who are logged in, are working with a page that has form fields, are involved in e-commerce activity or certain other excluded pages get served pages that aren’t cached.
Non-Cacheable Pages – 50 Virtual users
We created a load-test where approximately 10% of the pages being requested would be non-cacheable. We used the checkout page for the non-cacheable page.
At this level we noticed bursts of CPU usage to 100% but it was not red-lined and the server didn’t fall over.
We re-ran this test and doubled the number of non-cacheable page requests.
Finally, we re-ran the test with approximately 30% of requests being for non-cacheable pages.
Bottom line – for a reasonable mix of cacheable and non-cacheable pages the $30.00/month server should be able to handle the load without any issues.
These tests were all run on a real-world site with very complex functionality. For non-cacheable pages, each request might result in thousands of lines of PHP code being executed. As such they are much different from any of the other performance metrics you might read elsewhere.
What they illustrate is that a $30.00 per month, 2 dedicated cores, virtual server can keep up with some very very high loads. For sites that are less complex and primarily read-only, such as magazine type sites and business information sites, servers at this level can likely handle thousands of users without falling over.
Finally, keep in mind that the technology stack is a standard LEMP stack with very little tuning and with a basic free CloudFlare proxy service. Isn’t it amazing the kind of performance that you can get out of the box these days?