Tag Archive for 'WordPress'

Convert your Linux filesystem safely and easily (even on a VPS)

I was shocked to discover that converting one’s filesystem is simple as pie and totally safe. The process goes like this:

  1. Remove cruft from your system (optional)
  2. Reboot into a LiveCD environment (optional if the partition you want to convert can be mounted read-only without rebooting)
  3. Mount the partition you want to convert in read-only mode
  4. Copy the contents of the partition somewhere temporarily (ex. another partition, external drive, DVD, etc.)
  5. Unmount the copied partition
  6. Format the partition with your desired filesystem
  7. Mount the formatted partition and copy all the files back
  8. Edit /etc/fstab to reflect the new filesystem
  9. Reboot and profit

Thanks to Slicehost’s wonderful Rescue Mode with a 2GB Rescue Slice, I was able to use this method to convert my Gentoo VPS from ext3 to XFS. Here’s a step-by-step account. These steps were performed on a 256MB VPS at Slicehost. YMMV.
Continue reading ‘Convert your Linux filesystem safely and easily (even on a VPS)’

If you liked this post, please subscribe to my feed. Thanks for visiting!

Nginx with PHP as FastCGI on Gentoo Linux

Nginx (pronounced “Engine X”) is a high performance web server (and proxy server, but we will be using it as a web server here). In small VPS environments where memory is precious, Apache is at best overkill and uses memory that could be spent elsewhere (like MySQL query caching), at worst a terrible bottleneck that will consistently bring down your site under very moderate loads. If you are willing to live without .htaccess files and Apache-style mod_rewrite rules, Nginx is a great replacement that will lower memory usage and increase performance.

This is a draft. Comments, suggestions, corrections, improvements are very much welcome!

Continue reading ‘Nginx with PHP as FastCGI on Gentoo Linux’

WordPress internal object cache killed this site’s performance

As you may have noticed, this blog became very sluggish recently. Fortunately, I’ve narrowed down the cause of the lag to the WordPress internal object cache, which is supposed to increase site performance, but in my case it slowed down page load times by more than 10x, sometimes much more.

My blog’s symptoms:

  • Disabling all plugins and reverting to the default theme and displaying only 1 blog post on the homepage did not really affect my page loadtime.
  • The load delay was not an issue with PHP/MySQL at all. My page was completely executed and outputted by PHP in about 0.5-1 second (according to various plugins that showed the script execution time), but it took 10x that to cache the entire page to disk or load 100% of the page in a browser.
  • The page load lag has nothing to do with the browser on the client side. I tried Firefox, IE, Safari, and even external tools like Pingdom Full Page Tester.
  • The browser loaded 95% of the page and for some reason stalled for a long time on the footer section; making the footer empty didn’t help, and profiling the footer itself showed that PHP executed it in 0.06 seconds.

On a whim, I removed the following line that I inserted in wp-config.php to get back to a vanilla WP setup.

define(ENABLE_CACHE, true);

This line enables WP’s built-in object cache and is supposed to improve performance slightly. Problem solved!

This object cache supposedly caches database queries to disk to reduce CPU and database overhead. This should increase performance in most cases unless your disk I/O performance is very poor, like Dreamhost’s NFS storage system. This feature seems to be undocumented and had security issues in the past, but is commonly recommended as a safe way of increasing performance. I have heard that the object cache hardly improves performance, but I’d never imagined that it would slow my site down by 10x or more.

Disabling the object cache brought my page load times back to normal, with all my plugins enabled. I suppose the feature is disabled by default for a reason. If your blog is suffering from performance issues and your plugins or themes are not the cause, try disabling the object cache (if you enabled it). Comment out

define(ENABLE_CACHE, true);

in wp-config.php if needed.

However, some of the performance improvements in the upcoming WordPress 2.4 apparently have to do with the object cache. /me confused. :( I will try to find out more about what exactly the object cache does and what it did to kill my site’s performance. Thanks again, Jeff from NFSN, for helping me troubleshoot my site’s performance issues.

Bad Behavior and Squid’s default caching behavior don’t play nice

I wrote earlier about Bad Behavior sporadically blocking me from my own site. It turns out the problem was Squid’s default behavior of caching error messages for 5 minutes (my host deploys Squid in front of its server clusters for load balancing and other purposes). Thus, if a spambot or other undesirable gets blocked by Bad Behavior, and I or anyone happens to visit the site within 5 minutes, Squid will serve up the 403 access forbidden message.

Bad Behavior’s devevloper Michael Hampton and Jeff from my host NearlyFreeSpeech were both extremely patient and helpful in helping me solve this problem. They both independently provided me with this very simple solution: add

header("Vary: *");

after line25 in banned.inc.php in the Bad Behavior plugin.

The “Vary: *” header tells the cache (like Squid) that the content of this particular page changes based on unknown factors. Since the criteria for whether the cache should serve the same version of this page to future requests is unknown, the cache shouldn’t cache the page. Contrast the “Vary: *” header with the “Vary: accept-encoding” header where the cache will serve up the same version of the page to requesters with the same “accept-encoding” value, and get a fresh copy if the value is different.

I am told that, in the ideal world, Bad Behavior should not have to send such a header with its error messages because the official HTTP standards (RFC 2616) state that content should not be cached unless the Cache-Control headers explicitly allow it. However, Squid is “non-compliant” in this particular case as it caches error messages for 5 minutes unless the default negative_ttl setting is changed. Luckily, it’s not a painful choice to choose between being compliant with HTTP standards and being complaint with default Squid settings (which I assume are widely used). Sending an extra “Vary: *” header doesn’t seem to have any downsides.

Thanks again, Michael and Jeff, for helping me debug this problem and humoring my newbish questions.

Publish your FeedBurner feed on your own domain

Most bloggers know about the free FeedBurner service, a one-stop-shop for hosting, optimizing, publicizing and analyzing RSS/Atom feeds. However, did you know that you can access your FeedBurner hosted feed using your own domain instead of the tacky “feeds.feedburner.com?” For example, you can find my feed at http://feeds.tummblr.com/tummblr. I think that looks much more professional, and maybe it helps with search engine optimization (SEO) too?

FeedBurner provides a “PRO” feature called MyBrand which allows you to use your own domain to access FeedBurner-hosted feeds. It used to cost money but is now free thanks to Google’s acquisition of FeedBurner. The MyBrand page is tugged away in the “My Accounts” area after you login, rather than the “My Feeds” area. The instructions for how to use MyBrand are self-explanatory.

To use MyBrands, you must be able to edit (or tell someone to edit) your domain’s DNS records. If you own your domain name, there is no reason your DNS provider (most likely your webhost or domain registrar) should not allow you to edit or help you to edit your DNS records. If you are unable to edit your domain’s DNS records, you should raise hell and/or switch to a different DNS provider. I might make a post about free DNS providers in the future. But I digress…

Now, if only my FeedBurner account could give me a subdomain like tummblr.feedburner.com instead of a subdirectory feeds.feedburner.com/tummblr. That way, MyBrands would make make my FeedBurner feed accessible at feeds.tummblr.com instead of feeds.tummblr.com/tummblr; the latter still looks a bit silly.

Apologies if this post is stating the obvious. I see a lot of FeedBurner users who have their own domains but still link to their feed using “feeds.feedburner.com,” so I thought this feature must be a bit obscure. Or perhaps people aren’t bothered by using a third-party domain for their feed. Anyway, I will probably write another post about why exactly FeedBurner is so useful. Everyone recommends FeedBurner but as a newbie blogger myself, it took some digging around before I came to the conclusion that FeedBurner is better than WordPress’s built-in feed.

P.S. Am I the only one confused by the “PRO” labels on some FeedBurner featurers? I understand that “PRO” features used to cost money, so the label made perfect sense. But now that Google has made all FeedBurner features free, the label just confuses users who don’t bother reading carefully. Lots of people might assume “PRO” features cost money and not give them a second thought. Now that all features are free, there’s no reason to differentiate them. The “PRO” features aren’t necessarily more advanced or difficult for users to implement or understand.

Bad Behavior false positives: blocked from my own site

Update: My mistake. Michael Hampton is still supporting Bad Behavior. Maybe I’ll figure out what’s wrong after all.

I’ve disabled the Bad Behavior plugin because it was sporadically blocking me from my own site. Bad Behavior in theory blocks spambots and other desirables from viewing your website altogether, saving your bandwidth and resources and acting as a first-line defense, complementing anti-spam solutions like Akismet and the new Defensio.

I really love the concept, but since Bad Behavior blocks access entirely, false positives are very costly. Unwittingly blocking genuine visitors to my site would be very very bad. I’ve tried to find the problem following instructions from the FAQ and this blog post on false positives, to no avail.

Unfortunately, the plugin doesn’t seem to be in active development, and the email for reporting false positives appears to be dead. Oh well, I guess Akismet alone will have to do.

Redirect visitors from high-traffic sites like Digg to CoralCDN mirror using .htaccess

Regardless if you have the most sophisticated caching mechanisms in place (like WP Super Cache), the simplest and most effective way of surviving flash traffic from sites like Digg is to redirect the traffic to a mirror, like the free CoralCDN.

I personally think that the Coral Content Distribution Network is one of the most amazing yet underrated web invention in recent years. It’s so effective yet simple to use it’s like magic to end-users. By loading a URL like “http://www.tummblr.com.nyud.net/archivepage/“, that page is fetched and cached on the CoralCDN, which is a peer-to-peer network comprising of servers all over the globe. So Digg can send thousands of users to my CoralCDN mirror and use no more of my host’s resources and bandwidth than if a lone visitor hit my site. Read more about Coral on their homepage.

Without further ado, here is the .htaccess code that will redirect visitors from high traffic sites like Digg to your CoralCDN mirror.

# Heavy Site Redirect to Coral Cache
# Links incoming from heavy sites are redirected to the Coral Cache
# Exception: Coral Cache Proxy Servers
# Exception: Googlebot crawler
#
# CONFIG: Replace “yourdomain.com” with your target domain name.
# CONFIG: Follow the HTTP_REFERER RewriteCond examples to add or remove
# domains to the list of redirected sites.
#
<ifmodule mod_rewrite.c>
RewriteEngine On
RewriteCond %{HTTP_USER_AGENT} !^Googlebot
RewriteCond %{HTTP_USER_AGENT} !^CoralWebPrx
RewriteCond %{QUERY_STRING} !(^|&)coral-no-serve$
RewriteCond %{HTTP_REFERER} ^http://([^/]+\.)?digg\.com [OR]
RewriteCond %{HTTP_REFERER} ^http://([^/]+\.)?slashdot\.org [OR]
RewriteCond %{HTTP_REFERER} ^http://([^/]+\.)?slashdot\.com [OR]
RewriteCond %{HTTP_REFERER} ^http://([^/]+\.)?fark\.com [OR]
RewriteCond %{HTTP_REFERER} ^http://([^/]+\.)?somethingawful\.com [OR]
RewriteCond %{HTTP_REFERER} ^http://([^/]+\.)?kuro5hin\.org [OR]
RewriteCond %{HTTP_REFERER} ^http://([^/]+\.)?engadget\.com [OR]
RewriteCond %{HTTP_REFERER} ^http://([^/]+\.)?boingboing\.net [OR]
RewriteCond %{HTTP_REFERER} ^http://([^/]+\.)?del\.icio\.us
RewriteRule ^(.*)?$ http://www.yourdomain.com.nyud.net/$1 [R,L]
</ifmodule>

Credit: Benjamin Yu
Note: Removed “:8080” from “http://yourdomain.com.nyud.net:8080/” since CoralCDN now runs on port 80, the standard HTTP port. Yay! :)