Note that one can monitor progress with these changes using Google's analysis page at https://developers.google.com/speed/pagespeed/insights
One of the cheapest things you can do server-side is leverage browser caching with mod_expires. Apparently, even if a file is already in the browser cache, the browser will still query the server on every hit to see if the file has changed. No, the file is not transferred if it has not changed, but yes, there is still a demand made of the server. Unless you turn on mod_expires, which tells the browser in advance how long the file is good for. And thereafter, until the file expires, the browser will not bother the server to check if it has changed. Other then turning it on, there is little to configure with mod_expires except possibly to specify the expiry times in your VirtualHost or in global config file in the conf.d directory, for example:
CacheEnable disk /
There are three commonly mentioned possibilities for PHP opcode caching: eAccelerator, APC, and XCache. I do not see much to choose from between them performance-wise, but APC seems to be a very native PHP project, so I will go with that:
apt-get install php-apc
The first thing you will want to do is copy apc.php into some web root and have a look. There, apparently the most important thing to check is "Cache full count" which you want to keep pretty close to zero. To get there, I increased my cache size in /etc/php5/conf.d/apc.ini to:
Get and install your preferred version of the module from , ie.
dpkg -i mod-pagespeed-stable_current_amd64.deb
I am running my personal server on a rather small Rackspace Cloud machine with 256M of memory. A default LAMP (plus a couple Python web apps) install seems to occasionally (my websites are usually not THAT busy) choke and force a reboot. Let's try and avoid that:
First thing I did was install a PHP op code cache called php5-xcache that I have used before. It is a zero configuration slam-dunk, and my spidy sense suggests that it produces a tangible speed improvement.
All of the reading I am doing (see references below) prominently mention unloading unused Apache modules so as to reduce the memory footprint of Apache processes, so this seems like the first place to start. This is a minimal (not requiring hacking my default Ubuntu server Apache configuration too much) list of Apache modules I can get by on at the moment:
alias.conf cgi.load dir.conf mime.conf php5.load ssl.load wsgi.conf alias.load deflate.conf dir.load mime.load rewrite.load status.conf wsgi.load authz_host.load deflate.load headers.load php5.conf ssl.conf status.load
Now into the murky world of Apache MPM (Multi-Processing Modules). Reading the "Compile-Time Configuration Issues" section in , one is left with the definite impression that the worker MPM would be a better choice then the prefork MPM in a limited memory situation. So why does prefork always seem to be installed? A little experiment tells all:
apt-get install apache2-mpm-worker
will result in the removal not only of apache2-mpm-prefork, but also all PHP modules!  has the answer:
"Apache PHP module is reputed to be unstable in multi-threaded environments"
 goes on to describe a somewhat complicated procedure for making the multi-threaded apache2-mpm-worker module work with PHP. Maybe later, if all else fails. Or maybe switch to lighttpd as a web server. Now back to the stodgy old Apache prefork MPM....
 gives some nice details on how one might go about optimizing the prefork MPM configuration. top is telling me that my Apache processes are currently consuming roughly 30+M per process. My current default configuration is this:
which I am going to crank WAY down to this:
StartServers 5 MinSpareServers 5 MaxSpareServers 10 MaxClients 150 MaxRequestsPerChild 0
StartServers 1 MinSpareServers 1 MaxSpareServers 2 MaxClients 5 MaxRequestsPerChild 200
Interesting that the default value of MaxRequestsPerChild was zero. Apparently the point of setting this value to non-zero is to periodically force Apache processes to be killed and recreated, to combat memory bloat (aparently they do not release memory?). It is also worth noting that my server's CPU usage tends to hangout near zero, while memory is always maxed out and swapping is a regular cause of problems. In top I have seen a single Apache process top out at as high as 50% of memory. I think killing processes frequently to reduce memory overhead is probably the way to go.
And finally,  recommends setting a really small KeepAliveTimeout of 2. And  recommends keeping "Timeout" small, since I have so few processes and do not want them all to be waiting for a timeout at the same time. So I went for a Timeout of only 10 seconds.