Well, as my first post, let me touch on some wordpress performance problems, as I just ran into said problems while getting this blog running.
So, I setup this virtual server a couple weeks ago. On it, I installed a variety of things, including some other PHP-heavy sites. All of them work great; faster than I expected, in fact.
Today, I installed WordPress in a subfolder on an Apache VirtualHost (specifically, david.pryke.us, which, since you are here and reading this, you already know.) I performed the basic setup of wp-config.php and then navigated to the site to complete the setup. This took a while to run, but I figured that perhaps the MySQL instance on this server was taxed, and it just took a while to setup the basic database.
Once I clicked on the “Log In” button at the last screen, I realized that something was terribly wrong. It took 40 seconds or so to load the basic login page for me to enter my username and password. Once I entered them, it took another 40 seconds or so to get to the admin. I tried just loading the basic blog, without loggin into the admin…40 seconds. I started looking for WordPress performance problems on Google. Many of the results pointed me to resort to the default “Kubrick” theme and start from there (no problem, it was a default install, I’m already using that theme.) After that, it indicated to disable all the plugins and start enabling them one at a time, taking note of when big slowdowns start to happen.
Well, since this was a fresh, default install, I figured that was’t the major problem. While I am a SysAdmin, and have no problem going through things one at a time, I also hit on a post by Paul Spoerry about how to Diagnose slow WordPress performance using FireBug. I found that to be a great idea, and one that I should have thought of by this point, as a lot of my coworkers use FireBug to look at problems during website development.
So, I installed FireBug and inspected my site with it. Wow. 40.532 seconds for the basic index.php page, and then a few hundred milliseconds at worst for the rest of the jpg’s and such combined. So, I start looking for WordPress performance diagnosis, and I come across a WordPress forum topic regarding a similar problem. In there, I found to insert code like:
<!-- <?php echo get_num_queries(); ?> queries. <?php timer_stop(1); ?> seconds. -->
which, I found out later, was already in the Kubrick theme. One other thing I found and enabled in my footer.php was this:
You can see how long each query is taking with a few modifications.
In your wp-config.php file, add this line of code to the top:
define('SAVEQUERIES', true);
Then, in the theme’s footer.php file, you can do this to dump all the queries and how long they took:
if (SAVEQUERIES) {
global $wpdb;
echo '<!--\n';
print_r($wpdb->queries);
echo '\n--!>';
}
Then looking at the source of the page will show all the queries and a number showing how long they took.
After you do this, turn the SAVEQUERIES back off by setting it to false in the wp-config.php file. You don’t want it to spit out the queries all the time.
The key there, which I knew, but some other readers on that forum topic didn’t, was to put “<?php” before the code block, and “?>” after the code block in footer.php. I looked at the source of the page after I added those pieces of code, and it told me two things. The first line output this:
<!-- 21 queries. 40.195 seconds. -->
Which told me that it believed the database queries were taking over 40 seconds to perform. However, the second piece of output (from $wpdb->queries) told me something totally different. This command lists the SQL for each query, as well as how long it took to run that query. Each on was along the lines of 0.0001130104064941 or 0.00027084350585938, which, when added together, was still much less than one second. Something isn’t “adding up” here…
After reading the rest of that forum topic, someone mentioned a problem which went away when he ran the internal “wp-cron.php” script by hand, but came back every time he created a new post. Well, there are two important pieces of information here. One is that this internal cron script is scheduled to run again when certain actions are taken, such as creating a new post. The second thing, and important in my case, is that this is run from within the web server itself…specifically, from within the PHP parser.
Now, a key piece of info for my problem is that I am hosted on a virtual machine that lives on a non-routable IP, an RFC 1918 IP of 10.53.22.13; this is important in that the public IP of this site is 66.179.100.13 (at least, as of this writing, on November 3rd, 2008.) The PHP parser tried to connect to david.pryke.us/blog/….. and could not get there because the firewall & NAT machine “in front” of the server would not redirect traffic back down this network link to the 10.53.22.13 address when one of the machines on the same link asked for the public, routable IP of 66.179.100.13;
To resolve this, and make the long story short, I had to add a line in /etc/hosts that read:
10.53.22.13 david.pryke.us
Which allowed the server to see the “correct” IP for that domain name (david.pryke.us) and vioala! the server loaded the first default post in less than a second!
Problem solved. (This should never have been a problem, as I usually setup the hosts file on these servers right away…but I forgot in this instance. Oops!)