Skip to content
Solely for the Purpose of Catching $PAMRZ

WordPress/MySQL Tuning

dltj.org runs on a relatively tiny box — a Pentium III with 512MB of RAM. I’m running a Gentoo Linux distribution, so I actually have a prayer of getting useful work out of the machine (it server is actually a recycled Windows desktop), but the performance just wasn’t great. As it turns out, there are several easy things one can do to dramatically improve life.

The Configuration


The box is both a mail server (IMAP) and a WordPress server. A rough eyeball at the process accounting on the server shows that it spends about 40% of the time doing mail (mostly taken up by Clamscan virus scanning and spam checking) and another 40% doing MySQL and web stuff. Since there isn’t much dynamic content on the box and nothing else using the database but WordPress, I’m fairly confident that blog traffic is almost all of that 40%. I’m using MySQL 5.0.x, Apache 2.0.x and WordPress 2.0.x with about two dozen plugins.

Taking PHP Up A Notch


PHP is an interpreted programming language, meaning that each time a script runs it needs to be translated into something closer to machine code (called the ‘opcode’). (As opposed to compiler languages like C and Java where you compile the source code into an executable in one step and then run that executable in a second step.) For an application like WordPress, where the source code is not changing, this translation causes a lot of overhead. Fortunately, there is a PHP plug-in called the Alternative PHP Cache that will saved the translated opcode the first time the script runs and use it for subsequent invocations. Getting this set up is pretty easy (these are Gentoo-specific commands, your Linux distribution will vary and I am glossing over a number of distribution-specific details like how to install packages and where the configuration files will reside):

  1. emerge -aDNtuv pecl-apc will download and install PHP APC and its dependencies (yep — that easy…I love Gentoo)
  2. Change the configuration defaults in /etc/php/apache2-php5/ext/apc.ini. I’ve found that one shared segment of 20MB is enough, so I set apc.shm_size="20". The rest of the settings are as they came in the distribution.
  3. Restart your web server: /etc/init.d/apache2 restart

APC comes with a nifty PHP page that will give you cache statistics and details. If you copy /usr/share/php5/apc/apc.php into your ‘htdocs’ somewhere and execute that page from a browser, you’ll see what I mean. (This is how I learned that 20MB of opcode cache space was fine for my application.)

Kicking MySQL Into Gear


Database tuning focuses a great deal on memory management. Your RAM will always be an order of magnitude faster than reading blocks off a disk. RAM, of course, costs more per MB than disk, though, so you have to select memory management strategies carefully. WordPress is, of course, a read-intensive operation. In other words, the majority of SQL statements are SELECTs rather than INSERTs, UPDATEs, or DELETEs. With that in mind, we tune MySQL with a read-intensive strategy. I found some of the best guidance in Peter Zaitsev’s “What to tune in MySQL Server after installation” and the ez.no documentation on Optimizing for read performance.

The changes I made to my MySQL configuration file, in the [mysqld] section are:

key_buffer = 6M ; (Actually, a decrease from the default since I didn't seem to need as much)table_cache = 512max_connections = 25thread_cache = 16query_cache_type = 1query_cache_limit = 1Mquery_cache_size = 20M

The 20MB query cache limit seems to be just about the right size for me. I seem to get very close to the edge of that buffer, but never seem to go over.

Finishing Up with a WordPress Plug-in


One more thing is needed to make this all come together: Mark Jaquith’s Post Query Accelerator. As Mark points out on his blog, WordPress “always ask[s] for posts with post_date_gmt <= ‘$now’ where $now is set to the current time, to prevent posts in the future from showing up.” If one turns on cache querying as described above, the “problem with $now is that it changes [with each query], so the query is never exactly the same again and the cache doesn’t help.” Mark’s plug-in “freezes” the value of $now to 15 minute increments or to whenever a post is added/updated, which ever comes first. That makes the query cache useful again and all is well.

Simply download the plug-in from Mark’s page and enable it in WordPress. Note that this plug-in is not needed for WordPress 2.1 and higher as the core developers have solved the “$now” problem with the “future” post status.

4 Trackbacks

  1. ebyblog | February 24, 2007 at 6:58 am | Permalink

    links from Technorati My Ma.gnolia Links WordPress/MySQL Tuning in Disruptive Library Technology Jester Tweaking some configs. Toothpaste For Dinner blog – Second Life You could transform yourself into a giant penis for 200 fakebucks, but one could argue that you do that anyway by spending time in Second Life.

  2. [...] Well, something is still going wrong on dltj.org — despite previous performance tuning efforts, I’m still running into cases where machine performance grinds to a halt. In debugging it a bit further, I’ve found that the root cause is an apache httpd process which wants to consume nearly all of real memory which then causes the rest of the machine to thrash horribly. The problem is that I haven’t figured out what is causing that one thread to want to consume so much RAM — nothing unusual appears in either the access or the error logs and I haven’t figured out a way to debug a running apache thread. (Suggestions anyone?) [...]

  3. The Rule of Tech | June 17, 2007 at 12:00 am | Permalink

    links from Technorati, second article concentrates on “Optimizing Apache and PHP” and final part is for “Tuning your MySQL server”. More practical example is on Disruptive Library Technology Jester -blog which writes about WordPress/MySQL Tuning on a Pentium III with 512M RAM box which runs a mail server (IMAP, ClamScan, Spam) and an Apache (WordPress and stuff). Article contains setting up Alternative PHP Cache and some options for database tuning focusing on memory management. About MySQL

  4. Kramer auto Pingback[...] osa käsittelee Apachen asetuksia ja vastaavasti toinen osa
    keskittyy MySQL:n asetuksiin. Myös dltj-blogin vinkit ovat
    tarkistamisen [...]

Post a Comment

Your email is never published nor shared. Required fields are marked *
Human Detection Scheme
(What's this?)
Comment Preview

Additional comments powered by BackType

Subscribe without commenting

From the Disruptive Library Technology Jester (http://dltj.org/), printed on Thursday the 2nd of July 2009 at 7:24:08 AM EDT (-0400). The URL to this page is http://dltj.org/article/wordpress-mysql-tuning/

[Creative Commons Logo] This work is licensed under the Creative Commons Attribution-NonCommercial-ShareAlike 3.0 United States License. To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-sa/3.0/us/ or send a letter to Creative Commons, 543 Howard Street, 5th Floor, San Francisco, California, 94105, USA.