Today we’re going to compare the performance of a WordPress site before and after we install and optimize the WP Super Cache plugin.
We’re running Ubuntu 16.04 Server, Nginx 1.10, PHP 7 with the Zend OPcache, MariaDB, and WordPress 4.6 with a few other plugins (Akismet, Jetpack, Yoast SEO, and Google Analytics). The system itself is a humble virtual server with 1 “core”, 2 GB RAM, and SSD storage, costing $10/month.
To perform our testing, we’re going to use the ApacheBench utility, simulating 5,000 requests with 5 concurrent connections. It’s probably worth noting here that ApacheBench struggles to simulate realistic traffic patterns, so I wouldn’t rely on it alone for load testing. If you’re serious about trying to kill your web server, consider something like httperf or Siege.
Our WP Super Cache Optimizations
Here’s our Nginx server block, with the Super Cache optimizations:
server { listen 80; listen [::]:80; server_name mywebserver.com www.mywebserver.com; error_log /var/log/nginx/mywebserver_error.log; access_log /var/log/nginx/mywebserver_access.log; root /var/www/mywebserver.com; index index.php index.html; ## Start WP Super Cache Configuration set $cache_uri $request_uri; # POST requests and urls with a query string should always go to PHP if ($request_method = POST) { set $cache_uri 'null cache'; } if ($query_string) { set $cache_uri 'null cache'; } # Don't cache uris containing the following segments if ($request_uri ~* "(/wp-admin/|/xmlrpc.php|/wp-(app|cron|login|register|mail).php|wp- .*.php|/feed/|index.php|wp-comments-popup.php|wp-links-opml.php|wp-locations.php|sitemap(_index)?. xml|[a-z0-9_-]+-sitemap([0-9]+)?.xml)") { set $cache_uri 'null cache'; } # Don't use the cache for logged in users or recent commenters if ($http_cookie ~* "comment_author|wordpress_[a-f0-9]+|wp-postpass|wordpress_logged_in") { set $cache_uri 'null cache'; } # Use cached or actual file if they exist, otherwise pass request to WordPress # try_files won't find 'null cache' URLs location / { try_files /wp-content/cache/supercache/$http_host/$cache_uri/index.html $uri $uri/ /index.php?q=uri&$args; } ## End WP Super Cache configuration # Pass PHP scripts to FastCGI server listening on Unix socket location ~ .php$ { include snippets/fastcgi-php.conf; fastcgi_pass unix:/run/php/php7.0-fpm.sock; } # Caching of media: images, icons, video, audio, HTC location ~* .(?:jpg|jpeg|gif|png|ico|cur|gz|svg|svgz|mp4|ogg|ogv|webm|htc|woff|woff2)$ { expires 2M; add_header Cache-Control "max-age=120, public"; } # CSS and JavaScript location ~* .(?:css|js)$ { expires 7d; add_header Cache-Control "max-age=604800, public"; } }
Benchmarking
First, we’ll benchmark WordPress without WP Super Cache or any Nginx optimizations:
root@ubuntu:/# ab -c 5 -n 5000 http://www.mywebsite.com/ This is ApacheBench, Version 2.3 <$Revision: 1706008 $> Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/ Licensed to The Apache Software Foundation, http://www.apache.org/ Server Software: nginx/1.10.0 Server Hostname: www.mywebsite.com Server Port: 80 Document Path: / Document Length: 121787 bytes Concurrency Level: 5 Time taken for tests: 353.619 seconds Complete requests: 5000 Failed requests: 0 Total transferred: 610035000 bytes HTML transferred: 608935000 bytes Requests per second: 14.14 [#/sec] (mean) Time per request: 353.619 [ms] (mean) Time per request: 70.724 [ms] (mean, across all concurrent requests) Transfer rate: 1684.69 [Kbytes/sec] received
Now let’s install WP Super Cache and enable it with all recommended settings in the WP Dashboard:
root@ubuntu:/# ab -c 5 -n 5000 http://www.mywebsite.com/ This is ApacheBench, Version 2.3 <$Revision: 1706008 $> Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/ Licensed to The Apache Software Foundation, http://www.apache.org/ Server Software: nginx/1.10.0 Server Hostname: www.mywebsite.com Server Port: 80 Document Path: / Document Length: 121959 bytes Concurrency Level: 5 Time taken for tests: 8.567 seconds Complete requests: 5000 Failed requests: 0 Total transferred: 611489685 bytes HTML transferred: 609795000 bytes Requests per second: 583.65 [#/sec] (mean) Time per request: 8.567 [ms] (mean) Time per request: 1.713 [ms] (mean, across all concurrent requests) Transfer rate: 69706.64 [Kbytes/sec] received
Better, but let’s implement our optimized Nginx server block:
# ab -c 5 -n 5000 http://www.mywebsite.com/ This is ApacheBench, Version 2.3 <$Revision: 1706008 $> Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/ Licensed to The Apache Software Foundation, http://www.apache.org/ Server Software: nginx/1.10.0 Server Hostname: www.mywebsite.com Server Port: 80 Document Path: / Document Length: 121959 bytes Concurrency Level: 5 Time taken for tests: 1.361 seconds Complete requests: 5000 Failed requests: 0 Total transferred: 611030000 bytes HTML transferred: 609795000 bytes Requests per second: 3672.68 [#/sec] (mean) Time per request: 1.361 [ms] (mean) Time per request: 0.272 [ms] (mean, across all concurrent requests) Transfer rate: 438303.80 [Kbytes/sec] received
With a few simple changes, we’ve taken our WordPress site from handling 14 requests/second to 3,600+. Imagine what you could do on some real server hardware, or if you added Varnish, Memcached or Redis.