Most interpreted programming languages parse source files and translate/compile them into opcode/bytecode that are suitable to be executed in the virtual machine. Python for example, dumps the compiled opcode into the .pyc or .pyo files so when the same file is imported again in the future, no parsing and compilation needs to be done. On the other hand plain vanilla PHP does not really have a way to save cached opcode so that at every request, source files have to be parsed and compiled into opcode again and again.

So we have the PHP accelerators which are mostly opcode cachers + optimiser, which cache the compiled opcode to either memory or disk, so the scripts don’t need to be parsed and compiled again in subsequent requests. They greatly improve the performance, and even the up-coming PHP6 will have the APC built in by default.

Introducing XCache

Personally I am using XCache on most my PHP apps. From its introduction page:

XCache is a open-source opcode cacher, which means that it accelerates the performance of PHP on servers. It optimizes performance by removing the compilation time of PHP scripts by caching the compiled state of PHP scripts into the shm (RAM) and uses the compiled version straight from the RAM. This will increase the rate of page generation time by up to 5 times as it also optimizes many other aspects of php scripts and reduce serverload.

Maybe not 5 times, but there is definite improvement from a standard PHP installation without the opcode cacher. Here is a CPU utilisation graph for my VPS at Linocde — I took XCache off trying to debug a segfault issue, and put it back on a few hours later.

Performance with and without XCache

Installing XCache

Installing XCache on most Linux distributions is trivial. Most my production boxes are running Ubuntu now, so I just

$ sudo apt-get install php5-xcache

And restart my web server — it’s done! Or on my Gentoo development box:

$ sudo emerge dev-php5/xcache

The bundled xcache.ini (found in your PHP’s configuration directory) has pretty sane setting. You might wish to adjust xcache.size to reflect your memory size.

But Is It Stable Enough for Production?

An optimisation technique is useless, if it hinders stability. This is actually the reason why am I posting this story — because my PHP/FastCGI servers crash at least once a day that render the Lighttpd front-end returning “500 Internal Error”, which I suspect might be XCache related (although I usually don’t have a chance to debug the processes and verify).

It is not huge load — lighttpd is only serving around 4 requests/second. The crash also seems to be random, i.e. not always at the peak of the traffic, and it happens during weekends as well as weekdays (that site of mine gets around only 70% of traffic during weekends). I actually wrote a simple shell script to monitor the site every minute and if 500 Internal Error is detected, spawn-fcgi is restarted — but I can imagine my users must be very annoyed.

Or maybe there is just nothing wrong with XCache itself but the fault lies on PHP or Lighttpd — I have no idea. Easiest way is just disabling XCache for a few days and see whether my site still crashes. Might do that this weekend.