WordPress Renovation – Server Performance Tuning

This post is part of a series of posts detailing the renovation of my WordPress blog, http://byronpate.com. In my last post, I walked through steps to Nginx, PHP, and Percona setup on my new Vultr server. When I wrapped up that post I had everything setup and ready to go to host a WordPress website. In this article, I’m going to go a little deeper into server performance tuning for WordPress.

Server Performance Tuning for WordPress

Now I’m going to do some tuning of Nginx, Percona, and PHP to help maximize performance. Before I jump into the updates. I’m starting with a default Nginx server block that looks like this:

Enable Client Side Caching

I’m going to enable Client Side Caching to make sure that browsers cache images, stylesheets, and javascript. This is an important part of server performance tuning because it prevents static content from being downloaded repeatedly. I’ll add the following location block into my Nginx server block that tells the client that this content expires after 1 year.

location ~* \.(jpg|jpeg|gif|png|ico|css|js)$ {
expires 365d;
}

Enable TLS and HTTP/2 in Nginx

I want to make sure I’m using HTTP/2 for my website. To support HTTP/2 I need to enable TLS. In my last article I installed Nginx 1.10 and Let’s Encrypt, and in this version, all that’s needed is to enable HTTP/2 in my server block as follows.

Nginx Server Tuning

Now I’m going to update the main Nginx configuration. I’m going to apply the following server performance tuning to Nginx. In the Events block increase the worker_connections to 1024, enable multi_accept and epoll.

I’m going to disable Nginx Access Logging. I use Google Analytics to track activity, so the Access Logs are not really used. Error messages are still logged to error.log. But by disabling access logging, I reduce additional io on the server.

access_log off;

Last but not least I’m going to enable Gzip HTTP Compression by making the following changes to /etc/nginx/nginx.conf. Compression can have a huge performance benefit and its very easy to enable in Nginx. After restarting Nginx, you can confirm if Gzip is enabled using http://checkgzipcompression.com/

Percona Server Performance Tuning

I’m going to make a few tweaks to the Percona MySQL configuration. I’m making the following changes that will help optimize my server for running WordPress:

skip_name_resolve – Since all of my SQL connections will be coming from localhost I don’t need to enable DNS resolution. Turning this off will help with response time.

query_cache_size – This is a well-known bottleneck on queries, so it’s recommended to disable it.

innodb_flush_log_at_trx_commit – WordPress is mostly database reads, with a few updates and adds when authoring. Given that the transactional nature of the website is very low I’m turning off full ACID compliance to improve performance.

innodb_buffer_pool_size – One of the more important settings, this sets how much memory is allocated to table and index data caching. Setting it as high as possible is the best option. My server has 768MB, so I’m setting the buffer pool to 200MB or roughly 25% of the server’s memory.

To apply these changes I’m going to edit /etc/mysql/percona-server.conf.d/mysqld.cnf as follows:

PHP Tuning

Finally, for PHP 7 I’m going to make several updates. The first section includes the following changes:

max_execution_time – Set the PHP execution time to 600 seconds, the default is 0 or unrestricted.

memory_limit – Set the memory limit to 128MB

error_reporting – Disable verbose error reporting

display_errors – Disable showing error messages

log_errors – Disable error logging

user_ini.filename – Disable user-defined php.ini files

realpath_cache_size – Increase the number of open PHP files cached. For WordPress, this is a helpful setting.

cgi.check_shebang_line – Disable PHP CGI

The opcache settings enable and optimize OPcache. OPcache is an important feature in PHP7. It improves PHP performance by storing precompiled script bytecode in memory cache. Cached PHP scripts do not need to be loaded from disk and parsed on each request. I’m increasing the amount of memory that OPcache can use so that more of my WordPress files are stored in cache.