Tuning a webserver to avoid swapping

A lot of people run into a problem when they first setup a webserver — perhaps in a VPS or other small system — using default settings: the system will run fine at first, but when under load, probably when the owner isn’t around, it will grind to a halt. The owner comes back, tries to use the site, and it’s unbearably slow. Even logging into the server to see what’s wrong, can be unbearably slow.  The worst thing, but the common thing, is to log in eventually, reboot the server, and continue as before.

The usual cause of this is not realising that web / database servers need to be configured carefully for the memory use per connection.

For example, if you’re just running apache with mod-php, and PHP is configured for 128MB per connection, apache might default to 32 connections or more (it might even be 128 by default), which is a LOT of memory for a small VPS. Then there is your database on top, and all of its connections, caches, etc.

For a webserver, you should probably:

  • Turn off virtual memory
  • Carefully calculate your memory requirements for PHP, Ruby, python etc.
  • Run a SMALL number of dedicated fastcgi (or similar, see wsgi etc.) servers for the webapp/languages you need.
  • Tune these as far as reasonably possible. For example, you can configure how much memory PHP-FPM will use, and how many threads mongrel will spawn, etc.
  • Run a carefully tuned webserver, with lots of LIGHTWEIGHT connections: apache stripped down (google that) or nginx, or lighttpd. I’d recommend nginx.
  • Run these without in-process languages like mod-php. Instead, make them serve static files quickly (ideally using the linux kernel’s sendfile feature), but pass PHP requests etc. to the back-end handlers, like php-fpm via fastcgi or similar.
  • Run mysqltuner or similar tools to tune your database.

What you need to aim for is for the maximum number of processes, under full load, and full memory usage, plus any extra software like firewalls and cron jobs, to never exceed physical memory. If you do need to run heavy cron jobs etc., then enable virtual memory, but only if you’re sure there are quiet times for your server, like 3am, when it can afford to crawl. Otherwise, you need to take the hit and reduce the number of processes/maximum memory, or increase the server memory, to cope without swapping.

2 Comments

  • asd wrote:

    Instead of disabling swap which might cause some process to be killed it’s better to edit /etc/sysctl.conf and tweak vm.swappiness and vm.vfs_cache_pressure to reduce the amount of swapping (there are many websites explaining their function on google)

  • Lee wrote:

    If you read my post again, I’m advocating (in most cases) tuning things so as to not required disabling swap, allowing swap to be used for less frequent maintenance tasks, such as non-peak-time cron jobs. Tuning the swappiness etc. would help, too. But my main point is that you need to consider your actual process requirements, and specify hardware and tune accordingly. Disabling swap is NOT a problem, so long as you do this, and CAN improve your server’s responsiveness, when used correctly. Swap should NOT be considered suitable for all situations, just as running without swap should not be.

Leave a Reply

Your email is never shared.Required fields are marked *