LAMP Settings for a High-Performance Small Server.
With the VPS expansion you can now get a (very) small virtual private server (VPS) for a very affordable price. However, when you get a server with something like 256MB or 512MB RAM and a portion of CPU power, using default MySQL/PHP/Apache settings is a pretty bad idea.
Performance and scalability tuning of a server is more of an art than science, in the sense that there're no ready-to-use formulas. Optimal server settings depend on many unique factors: web-app code, traffic to the site, site's information architecture among other things. It's virtually impossible to really optimize server settings without thorough understanding of the web application and a lot of testing.
That said, you are not going to run newsweek.com or huffingtonpost.com on a 256MB slice. Also, the default settings are typically so off that it is possible to give you a much better starting point. I'd like to share with you some settings that have worked well for me. I am assuming you are running a small site or a blog, with the traffic of several thousand page-views/day, using Wordpress, Drupal or something of that kind. I highly recommend getting at least a 512MB VPS, but these settings are better than the default for a 256MB server, as well.
Following are some variables for various settings files that have been modified from their default values.
/etc/my.cnf:
thread_cache_size=4
skip-bdb
skip-locking
query_cache_type=1
query_cache_size=64M
query_cache_limit=8M
# Reduce max_connections to 16 for a 256M server
max_connections=32
key_buffer_size=4M
# Reduce the following two settings to 32M for a 256M server
tmp_table_size=48M
max_heap_table_size=48M
join_buffer_size=4M
max_allowed_packet=8M
innodb_additional_mem_pool_size=8M
innodb_buffer_pool_size=16M
innodb_flush_log_at_trx_commit = 1
# Server/Storage Engine Settings
default-storage-engine=INNODB
# for MySQL 5.0:
default-character-set= utf8
# for MySQL 5.1, use the following instead:
# skip-character-set-client-handshake
# collation_server = utf8_unicode_ci
# character_set_server = utf8/etc/php.ini:
; Drupal is memory-hungry, you will need at least 64M or 92M for Drupal,
; but 40M should be fine for barebones Wordpress
memory_limit = 48M
realpath_cache_ttl=300
realpath_cache_size=1M/etc/php.d/apc.ini
extension=apc.so
apc.enabled=1
apc.shm_segments=1
; Reduce shm_size to 32 for 256M server
apc.shm_size=48
apc.ttl=7200
apc.user_ttl=7200
apc.num_files_hint=1024
apc.mmap_file_mask=/tmp/apc.XXXXXX
apc.enable_cli=1/etc/httpd/conf/httpd.conf
KeepAlive On
MaxKeepAliveRequests 100
KeepAliveTimeout 3
# Replace /var/www with whatever directory you keep your virtualhost folders under.
<Directory /var/www >
AllowOverride all
Options all
Order allow,deny
Allow from all
Deny from none
# Insert filter
SetOutputFilter DEFLATE
# Netscape 4.x has some problems...
BrowserMatch ^Mozilla/4 gzip-only-text/html
# Netscape 4.06-4.08 have some more problems
BrowserMatch ^Mozilla/4\.0[678] no-gzip
# MSIE masquerades as Netscape, but it is fine
# BrowserMatch \bMSIE !no-gzip !gzip-only-text/html
# NOTE: Due to a bug in mod_setenvif up to Apache 2.0.48
# the above regex won't work. You can use the following
# workaround to get the desired effect:
BrowserMatch \bMSI[E] !no-gzip !gzip-only-text/html
# Don't compress images, videos and audio
SetEnvIfNoCase Request_URI \
\.(?:gif|jpe?g|png|flv|mp4|m4v|mp3|zip|gz)$ no-gzip dont-vary
# Make sure proxies don't deliver the wrong content
Header append Vary User-Agent env=!dont-vary
</Directory>Disabling Swap
Another thing that can adversely affect performance is if a server decides to start using swap partition for memory. On Linux, swap space is there to prevent running out of memory. However, Linux is somewhat frivolous in swapping, in that it may use swap even in the cases when it would not have ran out of memory. When linux uses swap for MySQL or Apache/PHP performance degrades significantly.
If you want to be absolutely sure that swapping never happens you can disable swap. This is dangerous because if you don't properly project your maximum memory allocation you may run out of space and server will crash. But sometimes the risk is worth the benefit of running the server at top speed. To disable swap: edit the /etc/fstab file and find a record that looks like:
/dev/sda2 swap swap defaults 0 0The first column shows the partition used for swap: /dev/sda2. It may be different in your case. To disable swap put a comment character ("#" pound character) in front of that line and run the following command as root:
swapoff /dev/sda2where the argument of "swapoff" should be the partition which swap was mounted on.
Static Cache
Another thing that could be a great idea for a blog on a small server is to put it behind a static-HTTP-cache like Varnish. That can really boost your scalability. Configuring Varnish is a complex and large topic that requires its own blog post, however.





Really useful.... but swap?
I think that this is the type of post that really helps the one person shops get the most out of the most common type of hosting they are going to get for medium size clients. Thanks! However, I think that turning off swap is just crazy for a server with this little memory. If you start risking total system crashes for a little more performance, it's time to upgrade to the (blazing fast) speed of a 512MB slice :) IMHO.
I agree about "bazling-fast
I agree about "blazing-fast 512MB" :) As for the rest: keep in mind that MySQL/Linux may start swapping way before memory gets dangerously low and causes a crash. The duo is quite (unnecessarily) proactive in swapping.
Also, keep in mind that when database is swapping your website's performance is not much better than that of a crashed server. Either way, if you are utilizing more memory than swap-disabled server can provide, you should probably upgrade, indeed.
This is awesome! I can't
This is awesome!
I can't tell if all the values in the above are for a 256MB server or just the ones that are commented - could you please clarify.
Thanks for a great post.
These values are optimized
These values are optimized for 512MB. They are closer to optimal than the default values for a 256MB slice as well, but with 256MB server you are so dangerously close to swapping (or crash if you disable swap) that you have to be very careful unless you are running some very low-memory-overhead application with low traffic.