Pro tip: Run the latest Nginx version on Ubuntu

For some reason or another, the version of Nginx available in the standard Ubuntu repositories is old. Fortunately, there’s an alternate repository maintained. The Nginx install page shows us how to add it:

sudo su -
nginx=stable # use nginx=development for latest development version
add-apt-repository ppa:nginx/$nginx
apt-get update
apt-get install nginx

If you get an error like:

-bash: add-apt-repository: command not found

you need to:

aptitude install python-software-properties

Compiling from source is a pain. Do this instead (tested on Ubuntu 10.10).

Proxy caching WordPress with Nginx

Nginx is a lightweight web server/load balancer/reverse proxy designed to drive blazingly fast websites. It has low resource requirements compared to Apache, the defacto standard for PHP-based applications, and can handle an order of magnitude more requests per second.

With WordPress, Nginx is often used in a few different ways: to serve static media assets, to execute PHP for WordPress, or to reverse cache Apache responses. You’ll want to install Nginx, put it in front of Apache, and then choose one option or go for all three. Mike Green has comprehensive documentation to cover the first and third scenarios. It’s more or less what I did at the J-School.

Epic foo is using Nginx as a reverse proxy cache. “Reverse proxy cache” means Nginx will generate a static cache of everything Apache responds with, and then serve this cache as long as you’d like. For us, this means homepage response time has dropped from an average of 1.5 seconds to around 25 milliseconds. On pages without a lot of secondary images and Javascript (e.g. not the homepage), load times are now wicked fast.

It’s worthwhile to note we’re only serving cache to non-authenticated users. Students and faculty expect our website to behave like an application, and to have changes they make appear immediately. This is less of an issue for other visitors. Caching also gives us protection against bursts of unexpected traffic.

Proxy caching was deceptively simple to implement. I spent around 15 work hours in September trying to get it to work, gave up until November, and then solved the problem in 15 minutes with a stroke of brilliance. Originally, I followed the configuration settings specified in Dan Collis-Puro’s awesome WordPress plugin and it took our setup to 80% completion. I then learned the most important thing is to tell Nginx to log cache hits; this makes it far easier to determine whether caching is working or not. The second most important thing is to turn proxy_redirect off. I still don’t fully understand what the declaration does, but it was the crucial missing piece. Seeing dozens of “HIT”s scroll by never felt so good.

Check out our commented master Nginx configuration file [txt] and the configuration file specific to journalism.cuny.edu [txt].

#wcnyc: Performance & Optimization

Matt Martz (@sivel) and Scott Taylor led one of the first sessions on WordPress performance and optimization.

“High performance is not high availability.”

Matt manages five personal servers, including one load balancer, two web servers, and two database servers. The Nginx load balancer is a 512 MB slice from Slicehost, web servers are Nginx with FastCGI and 1 GB a piece, and the MySQL database servers are 512 MB. HyperDB is a WordPress plugin which allows you to partition out your database. Matt has it configured such that reads are done from all of his databases, while writes are only to the master database.

Caching is done with Memcached, PHP APC caching, and Batcache. WordPress.com is Memcached, HyperDB and Batcached. LoadImpact.com allows you to load test your site with between 10 and 50 concurrent users and will give you the page load times based on the number of users. Matt’s load times start at about 1.75 seconds and actually go down over time because caching kicks in.

GlusterFS is a system utility to replicate data across all of your production web servers. Upload an image to one, copy to every. GlusterFS is nice because it works on both physical and virtual machines. Matt has the WordPress directory, PHP directory, and Nginx configuration syncing across his web servers.

In total, he easily handles 4 million pageviews/month across all of the machines.

“If it appears slow, it’s often because of the front-end.”

Scott Taylor discussed front-end optimization.

First, ensure the HTML code you write is semantically correct. The TwentyTen theme packaged with WordPress is a good example to follow. Overrides follow the rule of IDs first, then classes, then elements.

Combine scripts from different plugins to just one script to improve load times.

YSlow and Google Page Speed are good tools for front-end development. YSlow will tell you to make less HTTP requests, add expires heads, use Gzip (same thing as deflate), reduce the number of DOM elements, specify absolute image dimensions and a favicon, and cache AJAX requests.

Recommended resources from Scott include: Rasmus Lerdorf at Digg, anything from Steve Souders, and writing from Douglas Crockford.