In my ‘free’ time I help out my good friend Jensen run the infrastructure for Asphalt & Rubber. This has lead to some interesting projects over the years, scaling Wordpress and MySQL on a shoestring budget, migrating from a traditional data-center environment to fully AWS, working around both my work schedule and the peak readership hours of a truly world wide audience. Most recently I have finally had the time and opportunity to put in a real load-balancer and caching layer in front of the application servers, driven both by a new theme roll-out as well as scaling needs.
This new layer is in addition to the traditional Wordpress stop-gap measures like W3TC combined with memcached, as it is doing no-hit full page caching for any non-logged in users. Out of the box, Wordpress makes this a rather difficult endeavour, as by default every request sets session cookies, regardless of the user’s logged in status. As such, this requires some custom VCL scripting to strip off any un-needed cookies for unauthenticated requests or for any static assets that have no use for cookies, prior to them hitting the cache lookup layer.
Fortunately, there are a number of canned configurations for Varnish and Wordpress online, this is far from a unique problem, so I will not go into the VCL details here. For me, the fun part was getting some actual visibility into the performance of various subsystems, as HAProxy out of the box has a lot more detail in its logging than Nginx. Things such as time to full headers, time to connect to backend, and reasoning for each of the http status codes returned makes having a purpose built load balancer so much more rewarding that just throwing NGinx infront of apache/php-fpm for SSL termination.
As it stands now, after a number of configruation changes, we are averaging a .4 cache hit rate. Considering that there are a number of member only (meaning logged in user) feature articles, I consider this pretty good– Varnish easily handles the un-authenticated general population, only passing off logged in member requests to the object and database caching layers beneath. While I am sure there is plently more to do, this has stablized performance for now, all without increasing cost and only moderately increasing complexity.