Skip to content

WordPress, nginx, and Dreamhost

So I found the blog to be slow, really slow.

I checked my memory and cpu usage and it seemed all normal. The command ps -eF was useful for listing processes, but my host also has a graph of used resources and it all looked well within my limits.

I learned about apache benchmark and ran some tests such as ab -n 100 -c 5 http://www.mythiclogos.com/ and found that it would take between 1-2 seconds for the initial page to get back. From the server itself, the benchmark dropped to much less, but still high, I thought.

I tried some caching plugins. I have eventually settled on WP Super Cache which is a plugin I understand.

But it still was slow. I suspected Apache was being slow for some reason. I know that it can get crippled under heavy loads, but I have no heavy loads. Still, my host offers a drop-down box for switching the web server. So I tried nginx. It took me a day to figure out how it worked, how to get my wordpress sites to work with it using WP Super Cache redirects, and all that. And now I find the performance of my sites seem to be exceedingly fast.

The benchmark tests seem to suggest it is twice as fast, but I think that is an underestimate. Before when loading pages I would count to 6 before I had a page. Now, many of them are in a count of 2 or 3. But that is when I use the ones with cookies on them. When I clear the cookies, so that the blogs think I am just some guy visiting, there is no count. It seems instantaneous. That’s awesome.

The difference is that WP Super Cache serves cached pages to unknown visitors, but not to the known ones. As the maintainer, I can stomach a second delay to make sure that I have the most recent stuff and nothing weird happens. But to others, having a zero second delay is incredible. So WP Super Cache makes compressed html pages of the semi-dynamic pages. Some of the comments could get out-of-date, but whatever. It makes the primary page loads wicked fast which is what I care about. I imagine one could add some ajaxy thing to check for new comments and updates. I am sure there are already plugins for that.

I should note that nginx helps immensely with static html pages. I think it can work under tremendous loads without breaking while Apache crawls to a halt. But it does not help too much with PHP. I think it does keep the processes persistent and maybe the useful scripts in memory???, but for the most part, PHP is a separate process using FastCGI and nginx has nothing to do with it. It just does the pre-screening and serves static html pages.

One thing that I think is broken is the stats trackers. I believe they work by throwing in some PHP processing code that logs the users that visit. Since PHP is never touched, it can’t log that. One fix could be to do some sort of fake-download of an image or an ajax call to track the visitor. Not sure. It is a shame though as I have enjoyed seeing stats of visitors from around the world.

Anyway, the main code to get nginx working I got from a post about nginx+WP Super Cache. I added an extra line to deal with possibly a missing slash at the end:

location /blog/ {
# enable search for precompressed files ending in .gz
# nginx needs to be complied using –-with-http_gzip_static_module
# for this to work, comment out if using nginx from aptitude
gzip_static on;

# if the requested file exists, return it immediately
if (-f $request_filename) {
break;
}

set $supercache_file '';
set $supercache_uri $request_uri;

if ($request_method = POST) {
set $supercache_uri '';
}

# Using pretty permalinks, so bypass the cache for any query string
if ($query_string) {
set $supercache_uri '';
}

if ($http_cookie ~* "comment_author_|wordpress|wp-postpass_" ) {
set $supercache_uri '';
}

# if we haven't bypassed the cache, specify our supercache file
if ($supercache_uri ~ ^(.+/)$) {
        set $supercache_file /blog/wp-content/cache/supercache/$http_host/$1index.html;
}

if ($supercache_uri ~ ^(.+[^/])$) {
        set $supercache_file /blog/wp-content/cache/supercache/$http_host/$1/index.html;
}

# only rewrite to the supercache file if it actually exists
if (-f $document_root$supercache_file) {
rewrite ^(.*)$ $supercache_file break;
}

# all other requests go to WordPress
if (!-e $request_filename) {
rewrite . /blog/index.php last;
}
}

location / {
#### fill with exactly same as above
#### this is for those who have wordpress installed in one directory (blog/ above), but serving it from say the root directory.
#### seems to work fine.
}

Now, I find this to work out very well. The nginx wiki suggests that the if statements are evil because it is not an actual programming if statement. One cannot nest them and apparently their behavior is unpredictable from a novice point of view. Still, the above worked out well. It might be improved upon, but if something is working, well, leave it alone.

I also very much enjoyed the reloading of nginx. It was a single command that restarted it instantly and my changes were live. I also enjoyed that I could read and almost understand the configuration script. Compare that with some crazy apache rewrite rules that make me want to run away in terror.

There is much more to configuring nginx, but my host, Dreamhost, already had it all done and had it setup so that I can configure the domain-specific bits for each domain in my own directory. No need to mess around with the full config. It is a pretty sweet setup. I should mention that I have the VPS (Virtual Private Server) for $15 a month. It may be a little expensive for basic hosting, but man I enjoy having command lines and the ability to blow things up at will. They have a nice “Reboot” and a “Reset” option for the private servers that I have used often when experimenting.

In conclusion, caching and nginx leads to super fast performance with the supposed promised ability to withstand the deluges of a day of crazy hits in case a post becomes wildly popular.

Post a Comment

Your email is never published nor shared.