Optimizing Server Performance, Part 1

April 1, 2008 · Print This Article

Part 1 of 3: Part 1 | Part 2 | Part 3

I recently compiled a list of tips for people interested in easy ways to optimize server performance. The tips were directed at WordPress users, but many carry over to traditional web applications as well. After all, a blog is a specific kind of web site, so performance improvement tips for a blog will also improve the performance of a web site. That said, you will certainly get more value out of this book if you’re running WordPress and / or a MySQL database server. There are quite a few tips, so I’ve broken this post into multiple parts (yes, another one of those!).

workmen-1.jpgMy goal with this series of posts is to give you some fast and easy ways to prepare for traffic spikes. Of course, a crash due to a traffic spike is a good problem to have, but it would be better still if we could avoid it altogether. So to get you started quickly, try to follow these tips in order; i.e. start at the top of post one and work you way through each post. The tips near the top will give you the most bang for your buck, according to my determination of the trade-offs among tip priority, tip complexity, and time required for implementation. And keep tuning until you feel you’ve done enough to ensure that your server is able to handle the traffic. As we move lower down in this list, we’ll reach a point of diminishing returns. Each additional tweak could take more and more time for less and less improvement.

These posts contain the tips that I’ve picked up over the past several years. Some are from experimentation. Some were learned during consulting engagements. More are from administrators who have kindly shared their experiences with others. Many are from RTFM (“delving into the product documentation”). I’m not going to provide an overly deep explanation for each tip. You’re busy. You’ve got a site to administer.

I hope you find these tips useful.

Knowing When to Upgrade

Although it might be a hard decision to make, we must each make a determination about the viability of our current hardware and network. Not all servers, networks, or hosting accounts are created equally.

Server: your server must be physically able to handle high traffic loads. This means an adequate processor, plenty of RAM, and the often over-looked network card.

Network: hosts will have network limiters on their servers because they must parcel out their limited bandwidth to many servers at the data center.

Hosting account: your hosting account will have stated provisions for bandwidth. Larger hosts are usually much more generous with bandwidth. Some hosts will also make bursting provisions, which permit periodic spikes in traffic that are not maintained over long periods.

Upgrade Path

So if you’re using a shared hosting account (good ones are Lunar Pages and BlueHost) and your host is forgiving, you might need to be moved to a newer, more powerful server. You might also be forced to upgrade to a VPS plan. I am not a fan of entry-level VPS plans, so if you’re forced to go this route, don’t choose the least expensive plan and hope to maintain the response times you have with a shared account. A good VPS provider is Spry. Another option is to try moving to a host that uses grid service or cloud hosting, like Mosso or Media Temple.

If you’re using a VPS plan, you might need to consider upgrading to a more expensive plan that gives you a larger share of the processor and RAM. Or at least negotiate for an increased burst rate. If you’ve outgrown VPS entirely, you’ll need to move to a dedicated server. Good providers are iWeb and Liquid Web.

If you’re already using a dedicated server, you might need to look into upgrading your network card, adding RAM, using more and multi-core processors, or upgrading your hard drives. Or, you might need to add additional servers and configure a load-balancing solution. Or move MySQL to a server or servers on its / their own.

Hard decisions, especially when each step up the ladder involves increasing amounts of money.

Enough with this, let’s get started with the tips!

Install WP-Cache

WP-Cache is a WordPress plug-in that can have a dramatic impact on the performance of your blog. By dramatic, I mean anywhere from a 1,000 to 10,000 percent performance improvement, reducing response times by a few tenths of a second in many cases.

By default, all pages requested from WordPress are built dynamically; with WP-Cache, when a visitor requests a page or post, a stored, static version of the requested page is presented instead.

  1. Download the WP-Cache plug-in.
  2. Upload and extract it in your plug-ins folder.
  3. Activate it in your WordPress administrative panel.
  4. In Options | Reading, make sure that gzip compression is not selected.
  5. Open the Options | WP-Cache subtab, and it will attempt to configure itself.

Deactivate Plug-ins

It is possible to use too many plug-ins. Each plug-in requires additional server resources and processing time, and some require the use of additional software.

In all situations, a good practice is to only use plug-ins that you need to help you administer your blog, or that enhance the experience of your reader. In high-traffic situations, you need to be ruthless about trimming the fat.

One of WordPress’s nice features is being able to quickly activate and deactivate plug-ins. Go through your list and see if any plug-ins could be removed temporarily while you meet a spike in traffic.

Use Your Visitors’ Browser Caches

workmen-2.jpgFirst-time visitors to your page need to download all of the page components (HTML, CSS, JavaScript, Flash, images, etc.) before the page can be viewed, and this can require a fair amount of bandwidth.

But you can use the “Expires” or “Cache-Control” headers to make sure that their browsers cache those components. This won’t help with the first page request, but all additional page requests will avoid downloading those same resources again.

There are quite a few considerations to look at here, but many can be avoided if we just keep things simple. It won’t be optimal, but it will give you the most bang for your buck.

  1. Go to Presentation | Theme Editor in your WordPress administrative panel.
  2. Click the “Header” link on the right.
  3. At the very top (this must come before any other output), enter:
   ?php
       Header("Cache-Control: max-age=172800, must-revalidate");
       $strExpires = "Expires: " . gmdate("D, d M Y H:i:s", time() + 172800) . " GMT";
       Header($strExpires);
   ?>

You can also set an expiration date far into the future, but you run the risk that the user never sees the content that you’ve updated unless the file name changes. Setting expiration to two days (172,800 seconds) is a good tradeoff to get you past any traffic surges. Adjust as necessary.

Optimize your Database

The larger your database, the more advantageous this tip will be.

  1. Open phpMyAdmin
  2. Open your WordPress database (not information_schema)
  3. Perform a backup just in case
    1. Click the “Export” tab
    2. check the “Add DROP TABLE / DROP VIEW” checkbox;
    3. check the “Complete inserts” checkbox;
    4. check the “Save as File” checkbox;
    5. Click the “Go” button and download your backup
  4. Optimize your tables
    1. Click the “Structure” tab
    2. Click the “Check all” link below the table list to select all tables
    3. In the “With selected” drop-down box, select the Optimize tables option.

Serve your Images from Somewhere Else

This tip is often a tough sell, because it does require more time than the others to implement; however, its effect can be large.

Images eat a lot of your bandwidth, especially in blogs, and result in additional requests to your server. If you find that you use images in your posts, consider serving them from another server.

A user’s browser can only open two resources from one address at any one time. Offload your images, and your viewers’ browsers can open four simultaneous connections.
So your server is using less bandwidth, is being hit with fewer requests for resources, and your viewer’s browser is receiving twice as much content simultaneously. Not bad.
A service I would wholeheartedly recommend is Amazon S3; to a lesser extent, Steady Offload and Flickr.

Amazon opens up their server farms for several uses, one being their S3 storage service. You can access Amazon’s rock solid reliability for a very small price: $0.15 per GB per month for storage, and $0.20 per GB of bandwidth.

Assuming your average blog page contains 100 KB worth of images, you currently have 100 posts in your blog, and you post at a rate of 100 posts per year, your image storage cost is literally less than $0.01 per year. Your bandwidth costs would work out to $2 per 100,000 visits.

Steady Offload is an interesting service that mirrors your static content on their site. It’s effortless to set up, and you only pay for bandwidth you use. For high-traffic situations, I still would prefer Amazon’s reliability.

Flickr is a great option if you have a personal or non-commercial blog. They have restrictions against professional and corporate use, which can limit its usefulness for some. Also, it’s an image-sharing site, which might be a concern. On one hand, your images get more traffic, on the other hand, your images could be “involuntarily shared” with others.

I’d recommend that you stay away from ImageShack and PhotoBucket, although use of both is popular. ImageShack’s bandwidth per hour limit makes it useless during traffic spikes and both ImageShack and PhotoBucket are frequently blocked by corporate firewalls, and it’s never a good idea to alienate portions of your audience.

Don’t Touch your MyISAM Tables!

This is not a to-do tip, but rather a not-to-do tip. It had to be mentioned, as it’s a very common source of questions with folks who are just digging into MySQL. Many people contend that converting your MySQL MyISAM tables to InnoDB tables will have a large impact on performance, and this is true in certain situations.

InnoDB tables feature row-level locking, meaning that when a row in a table is being edited, only that row must be locked. In MyISAM tables, the entire table must be locked to edit a row.

In blogs, the only time you would require table locking is when content is being added, e.g. a comment or a blog post. As readers outnumber commenters and posters by an overwhelming majority, using InnoDB tables for a WordPress blog would actually hurt per-formance, not improve it.

If you were considering it, don’t do it!

That’s it for today. Check back in tomorrow for part 2 of this post.

Part 1 of 3: Part 1 | Part 2 | Part 3

Comments

7 Responses to “Optimizing Server Performance, Part 1”

  1. Optimizing Server Performance, Part 2 | The Mobile Technology Journal of Smilin' Joe Fission on April 2nd, 2008 10:36 am

    […] 2 of 3: Part 1 | Part 2 | Part […]

  2. Optimizing Server Performance, Part 3 | The Mobile Technology Journal of Smilin' Joe Fission on April 3rd, 2008 10:47 am

    […] 3 of 3: Part 1 | Part 2 | Part […]

  3. Blagovest on May 1st, 2008 6:00 am

    Check out the recently launched WP-Offload plugin. It integrates WordPress seamlessly with the SteadyOffload service. The static content in your posts (images, documents, movies) will get delivered from external cache servers, leaving your web server with the only task to construct dynamic pages.

  4. Joe Fission on May 1st, 2008 8:14 am

    Thanks for the heads up on WP-Offload. I will most certainly check that out.

  5. Richard on May 17th, 2008 5:19 am

    One of the best articles (x 3) on optimisation I’ve seen. To the point and covereing all those critical ares. I’m evaluating steady offload at the moment and so far it has been excellent at reducing page load times. One other thing worth noting is that some wordpress plugins leave data in the database, even after decativating and removal from the plugins directory. After many trials of plugins, this can leave more redundant data than active data, especially in the options table. This is a downside to performance. What users should always do is have a test site to try out stuff before transferring what they really want to their production site. This avoids database detritus.

  6. Joe Fission on May 18th, 2008 10:05 am

    That’s a great tip, Richard. Thanks for your feedback and review of Steady Offload.

  7. Hussein on July 7th, 2008 8:50 am

    Such a great post. I have learned a lot. I saw this from your comment in thenetfool.com

Got something to say?