From PHP-FPM to HHVM on Ubuntu

As a developer I enjoy using the latest and greatest…things. And, as a WordPress developer, I enjoy seeing how I can use the latest and greatest with the content management system I use on a day-to-day basis. Today I moved this very site from using PHP to HHVM. Here’s how.

You may have seen my previous post on how to set up WordPress on Ubuntu running onHHVM. If I’m holding my hands up, I cheated. I started from scratch – from a clean slate. That probably isn’t the situation in which you find yourself. You almost certainly have a site up and running with which you’re pretty happy, but, deep down, you really want to make it… better.

Chances are you have heard about HHVM (you probably wouldn’t be reading this post otherwise), but, just in case, here’s a quote from the main site;

HHVM is an open-source virtual machine designed for executing programs written in Hack and PHP. HHVM uses a just-in-time (JIT) compilation approach to achieve superior performance while maintaining the development flexibility that PHP provides.

There are many smarter and wiser people than me who have written posts about the speed benefits of HHVM over PHP. In my own, admittedly, very small statistical analysis, I find HHVM to be a metric shit-tonne faster than PHP. Sorry if I’m dazzling you with scientific terms.

Here’s the good news; I knew it was going to be easy to do this. That’s why I started writing this article before I actually began the process of doing it on this site that you’re reading right now.

Here’s the better news; there’s no bad news. It’s genuinely easy. Which is a huge testament to how well-built HHVM is. The only caveat is that the upgrade path I’m describing is for nginx. I don’t have any experience with Apache – if you do, please let me know and help improve this article.

Step 1: Update packages and install pre-requisites

sudo apt-get update
sudo apt-get install -y unzip vim git-core curl wget build-essential python-software-properties

That’s fairly straight-forward. Make sure you’re up-to-date and then ensure you have everything we need.

Step 2: Install HHVM

We don’t have to worry about running HHVM and PHP in parallel. So let’s just go ahead and install HHVM.

wget -O - | sudo apt-key add -

echo deb trusty main | sudo tee /etc/apt/sources.list.d/hhvm.list

sudo apt-get update

sudo apt-get install -y hhvm

Ridiculous, really, but that’s it. HHVM installed. Done, done.

Step 3: Configure HHVM

sudo /usr/share/hhvm/

This is asking HHVM to set itself up. If your setup is remotely like mine, it’s possible that you’ll see a warning: “detected clashing configuration“. For me, this makes sense, I’m not running a default config and, frankly, when I was setting things up I had no idea what I was doing so probably got it wrong.

Don’t panic. What HHVM is telling you now is that it’s not adjusted your config, (so if you have a live site, it’s still up and running) rather, you have to change your config yourself. Fortunately, it has placed an example hhvm.conf file alongside your normal nginx ruleset.

Step 4: Configure nginx for HHVM

Please understand that this section is very dependent on your own setup. If you have absolutely no idea what you’re doing with nginx configuration, then this may not be for you.

Take a look at the default hhvm config file;

nano /etc/nginx/hhvm.conf

For me, it looks like the following;

location ~ \.(hh|php)$ {
  fastcgi_keep_conn on;
  fastcgi_index  index.php;
  fastcgi_param  SCRIPT_FILENAME $document_root$fastcgi_script_name;
  include        fastcgi_params;

In absolute basic terms, this is saying, whenever the web server is asked to display a PHP file (or a ‘hh’ file) then this rule will take effect.

Next, look at your current nginx config ruleset. This could be anywhere on your filesystem. For me, I have a WordPress ruleset in my sites-enabled directory and hence;

sudo nano /etc/nginx/sites-enabled/wordpress

Chances are you will have a ruleset, within this file, in place for PHP. This needs to be removed because we are going to replace it with rules for HHVM (which completely replaces PHP for our server).

You may have a rule set similar to;

location ~ \.php$ {
    try_files $uri =404;
    fastcgi_split_path_info ^(.+\.php)(/.+)$;
    fastcgi_pass unix:/var/run/php5-fpm.sock;
    fastcgi_index index.php;
    fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
    include fastcgi_params;

You can either completely remove or comment-out this entire section as we’re about to replace it with HHVM rules.

You can either include the default hhvm.conf file thus;

include /etc/nginx/hhvm.conf;

Or you can place the contents of that file into your main nginx.conf file. (simply copy and paste it) replacing where you had your ~ \.php$ ruleset.

Step 4: Ensure HHVM starts on restart

This is a simple one-liner to ensure that if your server restarts, HHVM restarts too;

sudo update-rc.d hhvm defaults

Step 5: Restart all the things to make the switch from PHP to HHVM

OK. Believe it or not, that’s it. We’re done. We just need to restart nginx and, just for shits and giggles, hhvm too. We can do that via;

sudo /etc/init.d/nginx restart
sudo /etc/init.d/hhvm restart

Now what?

Refresh your website. That’s what.

Then start navigating around. HHVM can be a little slow when it’s “cold”. Which means that if you have very little traffic, this change may not affect your visitors greatly. However, if you start clicking through your site you’ll notice a huge increase in speed. For me, on this site, my average page load times went from 2.3 seconds down to 1.4 seconds. That’s a 60% difference. I’m going to say that again. My site’s response time has improved by 60% simply by switching to HHVM.

Load time for this website after switching from PHP to HHVM
Sometimes it’s a lot less than 1.4s. It can be as low as 0.4s!

Was it worth it?

Well, I personally think so. Not only was the switch from PHP to HHVM easy, but the load times on the front-end of this website have increased dramatically. On top of that, and this is strictly anecdotal, the dashboard area of this site is now blazing fast. It’s, quite honestly, nearly as fast as when I’m developing locally.

One thing I’ve realized whilst writing this post is that it’s very difficult to write a generic upgrade path for this process. Partly because every system is different but mostly because I’m simply not experienced enough at sysadmin-related magic. So I’m hoping that I can at least help people who are currently running PHP-FPM on Ubuntu 14.04. However, if this post doesn’t help you, maybe use the comments below to see if you can help others’ or other folk can help you?


    1. Nice work for getting it working! I’m not sure what you mean by “Chinese WordPress” Kingsley, sorry. I think it depends on how you’re displaying those social icons – is it from a plugin? If so, maybe try contacting the plugin dev. Is it from the theme? Try the theme dev. Also, you may be able to check if your server is set up so show specific file types – some social icons use .svg and on occasion a server isn’t able to display them.

Leave a comment

Your email address will not be published. Required fields are marked *