Blog Tags: 

Reducing the load on a small VPS by 80% in 5 minutes

A few days ago I noticed the average load on a newly setup VPS was too high relative to its workload. The server was noticeably sluggish. Load was high and a page the wiki it was running would occasionally take 10 seconds to load.

I didn't have too much time to kill but I decided I would at least try picking off the lowest hanging fruit before upgrading to a beefier, more expensive plan which would cost a few hundred dollars extra a year.

When I noticed swap usage was relatively high, I suspected the server was constantly moving memory in and out of swap.

One of the first things you should try when you're tuning the performance of a server is to reduce memory usage so that it doesn't use as much swap and can use more of your memory for disk buffering. Accessing buffered blocks from memory is a gazillion times faster than accessing them from disk.

So how do you reduce memory usage without reducing functionality? By tuning the trade off between memory and CPU time.

One example of this trade off in practice is pre-forking, which is a common technique used by many systems that can improve user-perceived performance. The principle is that by starting the process in advance of when it's needed then that bit of overhead is not experienced by the user who would otherwise need to wait for the process to start up before it can serve him.

The catch is that keeping spare processes around requires memory.

When you have a limited amount of real memory, then any performance gains from pre-forking can quickly evaporate due to reduced IO performance.

On this server, we didn't really have that much activity for things like mail or web, but many subsystems were configured (by default) to pre-fork at least 5 worker processes in advance.

This is a reasonable configuration for a dedicated server with lots of memory and hundreds of users, but not ideal for that cheap VPS you just setup for your workgroup.

I reduced memory consumption by over 200MB by simply decreasing the number of preforked worker processes for apache (20-25MBs per process), spamassassin (30MBs per process), and saslauthd. Average load dropped immediately by about 80%.

Total time spent picking this low hanging fruit: 5 minutes.


Liraz Siri's picture

Thanks for the positive feedback. It's delightful to hear that people are still benefiting from the posts on our little tips and tricks.
Andrew's picture

I'm using Amazon EC2 so I'd like to give this a try. Could you give me a clue where to start please?

Andrew's picture

For anyone wondering where to look to tweak Apache Prefork conditions, you'll find the settings in /etc/apache2/apache2.conf as follows:

<IfModule mpm_prefork_module>

    StartServers          3
    MinSpareServers       3
    MaxSpareServers      3
    MaxClients          50
    MaxRequestsPerChild   1000

These are my settings for now (using Amazon EC2 Micro Instance). Once you've made your changes, you'll need to restart Apache.

Jeremy Davis's picture

But IMO unless you have really low traffic A micro server just isn't going to cut it! In my experience if you want half decent reliability then a Small is the starting point. Once you start starving that of resources then it might be time to consider tuning... My 2c anyway...

As others have said elsewhere, perhaps it might be time to try one of the other lighter weight servers such as Nginx or LigHTTPd.

Liraz Siri's picture

Wow, that's one beefy machine. Use lighttpd or nginx. You may be surprised how well that works, once you set it up. :)

Liraz Siri's picture

Wow, 384MB is very little for a LAMP server. I'd reduce the number of children as much as possible to conserve memory but you're not going to get very far with that kind of firepower.

If resources are constrained I suggest using an asynchronous web server such as Lighty or Nginx. Good luck!

Jeremy Davis's picture

As per this article (and many of the comments) you can try tuning Apache to trade off CPU vs RAM. In the TurnKey appliances Apache is using it's (very general) default Debian config. I'm no expert but from what I hear there are lots of things that you can do to tune it to get maximum performance.

Another option is to use an alternative webserver such as LigHTTPd or Nginx. They are both significantly lower resource usage but much less user friendly (IMO) to configure. TurnKey has both a LigHTTPd or Nginx webstack appliances (with PHP & MySQL) but you'll need to install WordPress yourself.


Add new comment