6

I have been doing some experimenting with caching performance using loader.io and have been left with some puzzling results.

I was originally on a shared host that used a LAMP stack. Even with caching enabled it would fall over after 200 visitors in 1 minute.

I setup a basic LEMP (Nginx 1.9.12 + PHP-FPM7.0) 1GB Ubuntu droplet on Digital Ocean and copied my site across (subdomian multisite).

To get a baseline I setup the automattic wp-super-cache plugin using the PHP caching option for simplicity and ran a test. It worked extremely well so I ran the maximum I could on the free plan (10,000 in 1 min) and here are the results.

LEMP + wp-super-cache

This is amazingly good compared to my shared host that would never get below 300ms on a single request and would experience timeouts under any sort of load.

Everything I have read says that by using PHP caching in wp-super-cache I will get worse caching performance than using webserver caching as there is an overhead caused by the static pages being served via PHP.

Excited to see how quick I could get my responses I configured the fastcgi_cache to cache PHP files and then deactivated the wp-super-cache plugin.

I ran the load test again and here are the results:

enter image description here

The results are pretty much the same. The the first request is taking a little longer but it is the cached response I am interested in as that could most likely be optimised with some tweaking.

From this result I can't see any advantage to using fastcgi_cache over letting wp-super-cache handle the caching using PHP. Using the PHP caching is certainly a lot simpler when dealing with user generated subdomains and mapped domains.

I am only on the freeplan so I can't push the load test any higher but my needs don't exceed 10k in 1 min.

This has left me confused as every single article I have read on this says that there are significant performance benefits to using a caching rule in the webserver instead of serving a static file with PHP but with this setup that doesn't appear to be the case.

The fastcgi_cache is served directly from ram. Wp-super-cache uses php to read a static file from the SSD so I see why it should be faster so why isn't it?

This of course isn't an actual problem, I am just confused why my results are like they are and seem to contradict all the guides I have read.

Can anyone shed any light on why I am getting these results?

  • I think you have misunderstood how WP Super Cache works. Caching with PHP means that it needs to load WordPress, loads the plugin and some PHP script in the plugin loads and serves the cached document. You can also configure it to serve the cached document without the need to execute PHP, for example using .htaccess. The load speed may be similar but if you bypass the PHP execution, the resources needed from the server are lower, so you get more or less same load speed but you can serve more users. I can not tell you anything about fastcgi_cache as I've never used it. – cybmeta Apr 2 '16 at 8:24
  • You are repeating what I have said. If there is extra overhead why isn't there a longer TTFB? – Guerrilla Apr 2 '16 at 8:35
  • Sorry but I'm not repeating what you said. I said that resources needed are the huge difference, not so much in load speed as you have checked yourself. You are talking only about load speed and not about resources. So, there is not longer TTFB becasue there is not appreciable difference on that for low requests level. It's similar to what kovshenin is talking in his answer. You can get similar load speed but you can serve more requests. Note also that I talk about loading WP Super Cache files with PHP or with .htaccess, nothing about fastcgi_cache, I have zero experiencie with it. – cybmeta Apr 2 '16 at 9:39
  • 1
    @cybmeta Fair enough, I see what you are saying now. I went into my server graphs and can see that there are indeed twice as many writes when using wp-super-cache as opposed to fastcgi_cache, I am just not hitting enough traffic to make it a bottleneck. CPU utilization seems equal although it never gets above 10% so again it's not enough traffic to tell I think. No idea what is going on with free ram as that's not logged. I think really my surprise has been just how much traffic is needed to actually make a difference. – Guerrilla Apr 2 '16 at 9:43
5

Nginx is really good at concurrency (PHP not so much) so you should try a bit more than 180 requests per second. Maybe 500, or 1000 depending on your server resources and network throughput.

The fastcgi_cache is served directly from ram. Wp-super-cache uses php to read a static file from the SSD so I see why it should be faster so why isn't it?

It depends. First of all, whether fastcgi_cache is served from memory or not depends on your fastcgi_cache_path. If it's set to a tmpfs mount, then yes, it will be in memory. If it's set to a regular non-tmpfs directory, then it will be served from disk.

But disk doesn't always mean the actual disk :)

When you access a file from disk, Linux will cache it in memory, so the next time you access the same file, it will be served from memory. This is why most tests with loader.io, apache-bench and other tools that "hammer" the same page are flawed. They all cause your stack to access and serve the same files available in memory. This is why your WP-Super-Cache PHP option is likely not causing significantly more disk IO than Nginx and thus seems just as fast with low concurrency.

  • You are right! It wasn't mounted right. I am going to re-run the test with it mounted to tmpfs and see if there is a difference. You are definitely right in what you say. When there are thousands of pages getting accessed and one page spikes the ram will have a lot more pages loaded into ram which is a much harder thing to test for. I am just playing with setups at the moment and looking at the TTFB as a rough indicator of performance. The main thing I want to be prepared for is sudden spikes in traffic if content goes viral. – Guerrilla Apr 2 '16 at 8:49
  • If you'd like to see the PHP overhead, you can also just add the $upstream_response_time to your Nginx access logs. Under low concurrency, you'll probably see that for cached requests the overhead is a very small fraction of your overall TTFB. – kovshenin Apr 2 '16 at 9:35
  • Thanks for the tip. That is a much better way to see what is going on. – Guerrilla Apr 2 '16 at 9:46
  • P.S. If you want to simulate "real" traffic, you can grab a sample from your production access logs and replay them on your load testing environment with siege (--file) or httperf (--wlog). You'd be missing cookies, sessions and whatnot, but it's still much better than hitting a single URL. – kovshenin Apr 2 '16 at 9:58

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.