When we asked our readers what topic they’d like to cover in our tutorials three stood out the most:

  • Site speed optimization
  • Security
  • WP Admin speed optimization

We’ve covered the former two in our previous tutorials, so today, it’s all about optimizing your belowed wp-admin.

Due to it’s dynamic nature we can’t do page caching, but that doesn’t mean we can’t make it snappier!

Note: The techniques I’ll show you here speed up your WordPress in general (not just the admin), but if you do any kind of page caching (described in another tutorial) then it won’t have much impact on the visitor-facing side.

Before we get started

In order to follow this tutorial, you’ll need your own virtual private server (see this tutorial if you don’t have one), running Ubuntu 14.04 x64 and Nginx as the web server.

Note that actions we’ll perform here may not only break your WordPress but the server as well, so make sure you have backups - or even better - try it out in a staging/testing environment first.

Y U slow wp-admin?

There are two processes that take place once we load any wp-admin page: PHP processing (compiling PHP code into code that computer can understand) and MySQL queries (database operations). The more plugins you have, the slower your wp-admin gets. Sounds familiar?

Luckily, we can optimize both, PHP processing with HHVM and MySQL with object caching (more on that soon).

Install HHVM

HHVM is a virtual machine, developed by some smart engineers at Facebook that basically replaces PHP-FPM as our PHP processor. Well almost; The problem is that it’s what we called a bleeding edge software, meaning it has not been extensively tested in production environments (outside Facebook, that is), so what we’ll do is use both; HHVM will be our primary PHP processor with PHP-FPM as a fallback.

This way we get all the benefits that HHVM brings to the table and PHP-FPM will take over in case it crashes. Worry not, this all takes place automatically in the background so visitors won’t even notice that something went wrong.

To install HHVM, enter the following commands (as per official documentation):

$ sudo apt-get install software-properties-common
$ sudo apt-key adv --recv-keys --keyserver hkp://keyserver.ubuntu.com:80 0x5a16e7281be7a449
$ sudo add-apt-repository 'deb http://dl.hhvm.com/ubuntu trusty main'
$ sudo apt-get update
$ sudo apt-get install hhvm
WordPress HHVM installed
HHVM installation

Now that HHVM is installed, we need to install it as a FastCGI interface, so run:

$ sudo /usr/share/hhvm/install_fastcgi.sh

Now install (or replace) the command line interface (provided by php5-cli) with HHVM:

$ sudo /usr/bin/update-alternatives --install /usr/bin/php php /usr/bin/hhvm 60

And last, make sure HHVM is started automatically, when system boots up:

$ sudo update-rc.d hhvm defaults

To make sure it’s working properly, enter $ php -v and you should see something like in the following screenshot:

WordPress HHVM version
HHVM version

Now that HHVM is working properly, it’s time to configure Nginx to connect to it rather than to PHP-FPM, but we need to make a small correction first (optional, but my personal preference). Edit /etc/hhvm/server.ini, comment out the line with the port and the following line to it:

hhvm.server.file_socket=/var/run/hhvm/hhvm.sock

The final file should look like this:

WordPress HHVM ini
HHVM server.ini

Restart HHVM ($ sudo service hhvm restart) and you should be all set for Nginx configuration.

Open your virtual host file for the WordPress site you’re configuring this (in my case, that’s in /etc/nginx/sites-enabled/www.wp-kickstart.com):

$ sudo nano /etc/nginx/sites-enabled/www.wp-kickstart.com

In there, locate the location block responsible for PHP processing and replace it with these two:

location ~ \.(hh|php)$ {
  proxy_intercept_errors on;
  error_page 502 = @fpm;

  try_files $uri /index.php;
  include fastcgi_params;
  fastcgi_pass unix:/var/run/hhvm/hhvm.sock;
  fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
  fastcgi_index index.php;
}

location @fpm {
  try_files $uri /index.php;
  include fastcgi_params;
  fastcgi_pass unix:/var/run/php5-fpm.sock;
  fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
  fastcgi_index index.php;
}

Notice the error_page 502 directive? That’s our security net; If, for some reason, HHVM crashes or doesn’t respond to the request, PHP-FPM takes over and processes it as if nothing happened.

Install Monit

This step is optional, but it’ll make sure that HHVM gets restarted properly, whenever it consumes to much memory or processor. And you don’t want to check manually whether HHVM crashed. Because you have other stuff to do.

Monit is a process (running in the background) that’s constantly checking other processes, in more than one way: How much resources they use, are they even running, are the listening to correct addresses/ports, etc. Monit is what you’d call a system guard dog.

Installation is simple, just run the following command:

$ sudo apt-get install monit

This will install and start Monit, but it won’t check any processes out of the box, for that we need to add a configuration file:

$ sudo nano /etc/monit/conf.d/hhvm

add the following contents in:

check process hhvm with pidfile /var/run/hhvm/pid
  group hhvm
  start program = "/usr/sbin/service hhvm start" with timeout 60 seconds
  stop program = "/usr/sbin/service hhvm stop"
  if failed unixsocket /var/run/hhvm/hhvm.sock then restart
  if mem > 400.0 MB for 1 cycles then restart
  if 5 restarts with 5 cycles then timeout

Before we restart Monit, open it’s main configuration file /etc/monit/monitrc and around line 50, you should see a set mailserver directive. Uncomment it and enter your mail server info so it looks something like this:

set mailserver smtp.gmail.com port 587
username "your_email@example.com" password "your_password"
using tlsv1

Then scroll down the file, and at line with set alert (around line 115) add your email to be alerted when anything goes wrong:

set alert your_email@example.com with reminder on 15 cycles

If you want to enable Monit status reporting, you should also locate the set httpd directive (around line 123) and make sure these lines are uncommented:

set httpd port 2812 and
use address localhost
allow localhost

Save and close the file, then restart Monit in order for the configuration we just did to start working:

$ sudo service monit restart

To check our services’ statuses just run $ sudo monit status.

That’s it, your loyal guard dog Monit is now monitoring HHVM. If you want to monitor other services I’ve written a gist with common ones configured - just copy them into separate files (in the same directory that we configured HHVM in) and restart Monit.

Improve object caching with Redis

With HHVM up and running we improved PHP processing time so now, let’s focus on the second mayor bottleneck: MySQL queries.

WordPress comes with it’s own object caching solution but the problem is that it’s not persisted (saved) across queries, meaning it has to be re-generated on every request. Clearly, that doesn’t help us much in terms of performance, so we need to make it persistent.

One way to do that would be to save it to the database, but that defeats our purpose to make less queries, which is why we will store them in Redis. Redis could be considered a database engine that stores data not on hard drive but in memory (which is orders of magnitude faster to write to and read from compared to the hard drive).

Installing Redis only takes one command:

$ sudo apt-get install redis-server

There is no configuration needed, it works out of the box!

Since PHP doesn’t come with Redis support we also need to install the module for that:

$ sudo apt-get install php5-redis

Now that Redis is running (and PHP knows how to connect to it), it’s time to tell WordPress that it should use it for object caching.

First, you need to open wp-config.php and let WordPress know what host and port Redis runs on, and add a salt to keys (especially important if you’re running multiple WordPress sites on the same server):

define( 'WP_CACHE_KEY_SALT', 'mydomain_' );
$redis_server = array( 'host' => '127.0.0.1', 'port' => 6379, );

Now we need to install WP Redis plugin. Do not activate it as you’ll most likely see an error; What you should do instead is copy the object-cache.php file that it comes with, and put it in the wp-content:

$ cd /path/to/wordpress
$ cp wp-content/plugins/wp-redis/object-cache.php wp-content

That’s it, WordPress will start caching to Redis automatically when it finds the object-cache.php file in place! To verify it’s working, run $ redis-cli monitor and refresh the page (while being logged in). What you should see is Redis activity log of keys being set and retreived.

Conclusion

Caching is an important measure that all web applications (and WordPress is no exception) need to leverage in order to provide great user experience - nobody likes to wait for slow responses!

With HHVM and Redis, we’ve taken an important step in making wp-admin fast and enjoyable to use.

Do you have any tricks of your own? Let me know in the comments below.

New Call-to-actionQuality: The Codeable Differene