Using PHP with FastCGI

Making PHP faster for busy sites

If you expect very heavy traffic for your site, you can improve the performance of your site by running the PHP interpreter as a "FastCGI" process. This should achieve acceptable performance even for very busy sites (in tests, we've found that rates of 50 to 100 requests/second can easily be sustained). But this configuration is a bit more complicated, so we recommend that you do not use it unless your site is busy enough to need the extra performance.

FastCGI is a protocol which allows a web server such as apache to invoke another program to serve a page, but without the overhead of CGI (which needs to fork a process for every request) or the security problems of running scripts in-process in the web server (discussed above). PHP versions 4 and later support FastCGI in one of two modes:

  1. run a handler for each PHP page as a separate process;
  2. run one or more PHP interpreters, each of which can serve any PHP page.

The second of these is almost always better, for obvious reasons, and it is the configuration we describe here. (Note that these instructions assume that your website is configured in a fairly straightforward way. You'll need to adapt them as necessary for more sophisticated setups.)

To set this up, start by creating a directory called fcgi in the root of your web site. Inside it create a script called php, containing the following:

#!/bin/sh
PHPRC=/etc/php5/fcgi exec /software/bin/php5 "$@"

and make it executable. (We use a wrapper script rather than a symlink because apache is very picky about file permissions and symbolic links. The assignment of the PHPRC environment variable is required to make PHP read a slightly different configuration file, since the value of the cgi.fix_pathinfo must be 1 for FastCGI and 0 for normal CGI.) Also create a .htaccess file in the same directory:

Options +ExecCGI
SetHandler fastcgi-script

which tells apache to run scripts in the /fcgi/ directory as persistent FastCGI processes. The next step is to have your individual PHP files processed using this interpreter. To do this, add the following lines to a .htaccess file in the root directory of your site (create one if none already exists):

AddType application/x-httpd-fastphp .php
Action application/x-httpd-fastphp /fcgi/php

And once you've done that, everything should Just Work.

Testing it first

But... since you probably want to make sure that nothing on your site breaks when you make this change, here's a simple way to test everything first without disturbing the normal operation of your site.

First, make a copy of all (or some) of your .php pages under new names ending .qhq, for instance with this shell command:

for phpfile in `find . -name '*.php'`
do
qhqfile=$( echo $phpfile | sed 's/\.php/.qhq/' )
cp $phpfile $qhqfile
done

Now we have apache interpret these files using the FastCGI PHP interpreter. Add the following to a .htaccess file in the root directory of your website:

AddType application/x-httpd-fastphp .qhq
Action application/x-httpd-fastphp /fcgi/php

Now try browsing some of the .qhq files you've just created. If everything is working properly, they should work exactly like their .php counterparts. If not, you'll need to debug the problem, presumably by reading the messages logged to your server's error log. Many common problems are the result of incorrect ownership and permissions of the .../fcgi/php and the individual .qhq files.

Once that's all working, you can change the AddType line in the root .htaccess file to refer to .php files, and everything should be ready to go. Having done that, delete the .qhq files:

find . -name '*.qhq' | xargs rm

and you're all set.