Wordpress - How well does WordPress scale?
Clearly nothing scales as well as static files served by a fast web server and any CMS that has to figure out what to load and then load it will not perform as well, WordPress or otherwise. One of the issues is the number of database queries required per URL request and my 2 prior years experience working exclusively with Drupal and now 2+ years with WordPress is that WordPress is much better in that department.
That said, almost nothing with any power is going to scale "out-of-the-box"; it's all about what can you do as your scalability needs grow?
On the low end of "lots of traffic" there are great caching plugins and integrations with inexpensive CDNs you can do a pretty good job on a no-IT budget and low hosting budget. Here are some other questions & answers to review:
- Steps to Optimize WordPress in Regard to Server Load?
- Options for CDN with WordPress Including Supporting Plugins?
- Configuring WordPress for Amazon CloudFront Caching?
There are options for profiling to identify performance bottlenecks:
- Profiling a WordPress Website for Deployment on Shared Hosting?
Once bottlenecks are identified you can do localized optimization with things like the Transients API. This Q&A gives an example that can be optimized using Transients API and shows how:
- Using WP_Query to Query Multiple Categories with Limited Posts Per Category?
If you thing really get want to pull out the big guns you can configure Memcached, HyperDB, Nginx and/or more to speed things up (it seems the latter is really evolving into the way to get amazing scalability out of WordPress):
- Enable Memcached for your WordPress
- How To Speed Up WordPress With Nginx And WP Super Cache
- HyperDB
- Nginx as a front-end proxy cache for WordPress
And finally there are emerging WordPress-focused webhosts specializing in performance such as WP Engine, ZippyKid and others:
- Best-of-Breed features of a high-end WordPress web host?
So the good news is all of the scales very nicely; from the very low end of free and easy with technical complexity and cost only grow as traffic significantly grows. Start small with WordPress and it will be great. If your traffic does grow and you are monetizing it even reasonably well you'll find it very cost effect to scale as you need it.
At least IMO. :)
Don't expect much from shared hosting--don't blame WordPress for slowness if you're on a shared host. Shared hosts might cram 1000s of accounts into one server. So you can spend all day optimizing a $10/month account and it won't matter. Also watch out for marketing buzzwords--just because it says "cloud" doesn't mean you're not sharing one server with 100s or 1000s of people.
I don't think cache plugins are necessary at this point. If you look at the WP source code, there's already advanced caching baked into the core. A cache of the cache of the cache of the cache--watch out, this can be counterproductive.
The main thing slowing you down is slow MySQL queries and WordPress out-of-the-box shouldn't give you trouble here. However, I had to "LIMIT" my comment queries because I had 50,000+ comments. (Is this fixed yet?) Also, if you're doing anything atypical (like 1000s of categories?) that could be a problem too.
I use a Linode 512 with NginX and "top" shows PHP and NginX doing their work in less than 1/100th of a second per request. Nearly all the CPU time is tied up with MySQL. You could serve 1 million pages per month with a $20 Linode, but once you start adding plugins and photos, I think you'll need a "1GB" Linode. From my point of view, it's pretty much linear: If pageviews double, just double the size of your Linode.
Disclaimer: I don't work for Linode.
Update (~2 years later) since you want to cache parts of a page with PHP, here's a simple solution that I use that's surprisingly fast. I'm caching several separate parts/portions per page within 1/100th of a second. Seems like a ramdisk could make this even faster but it's plenty fast for my needs:
$cache_file = "./cache/portion-1". $since; // maybe round() this $since timestamp
$cache_life = 1000; // seconds to keep this cached
$filemtime = filemtime($cache_file); // returns FALSE if file does not exist
if (!$filemtime or (time() - $filemtime >= $cache_life)) {
// heavy lifting starts
$output = 'Heavy!';
// heavy lifting ends
if (!file_put_contents($cache_file,$output,LOCK_EX)) { echo 'error'; } // save the cache
echo $output;
} else {
// load from cache
$output = file_get_contents($cache_file);
echo $output;
}