I have a VPS with 256MB of guaranteed memory, and no burst/swap. Having little memory like this is quite common for a VPS and I want to know how to make the most of it while running websites. By far the biggest culprit for taking my memory is Apache and I'm not convinced that the default setup makes sense on a VPS.
I know there are other daemons out there that use considerably less memory, such as lighttpd, but enough people (myself included) are going to use Apache regardless (they might require some of the advanced features after all) so it is worth knowing how to get the most out of it.
Apache 2 has various mpm options, most notably prefork and worker. As I understand it the prefork method forks processes to handle requests ahead of time, and can fork more on demand if required, each process handles one request at a time. Worker uses threads, again created ahead of time and on demand, each thread handles one request at a time.
With the default configuration and prefork Apache spawned 6 processes each taking about 5MB, so there goes 50MB in total. With workers it wanted to create 50 threads, each with a 10MB stack, this instantly went over the memory limit so wouldn't start at all. Thankfully the stack can be adjusted using the ThreadStackSize setting so it can be made to run, but even after this what do you really have for your memory?
One problem with having one request per process/thread is that, again by default, Apache has a keep alive setting of 15 seconds. This means that once a request has been processed, the process/thread is then kept around for up to 15 seconds in case the client wants to do anything else. With prefork that is 5MB of memory being used, and even with threads with a reasonable 1MB stack size there is still a huge amount of memory wastage on a connection that might not even do anything. Meanwhile other visitors might be getting out-of-memory problems as Apache tries to spawn more handlers to meet demand.
I think it should be fairly obvious that the worker mpm is the best option here, if everything works fine with a 1MB stack then the thread overhead is considerably lower than the process overhead.
The new events mpm should relieve this problem as it uses an event queue to keep an eye on keep alive connections rather than a whole thread. Unfortunately this mpm is not considered stable yet, so in the mean time I am wondering if VPS users should just disable keep alive, or at least adjust it to just a few seconds.
The benefit of keep alive is that it reduces network traffic and CPU load as there is a small amount of overhead in setting up a new TCP connection. When servers had 400MHz chips and massive 256MB of ram this was a good trade off. But now VPS often have access to much more powerful processors, and the same 256MB isn't considered massive any more so a lot of applications are less frugal and less adept at running in this environment.
In the unlikely even that Apache had 200MB to play with, using 1MB threads means that the system can handle 200 idle connections before running out of resources and failing to handle new connections. With a keep alive of 15 seconds you can support 200 connections per 15 seconds. In light of the fact that many newer browsers will open 4 simultaneous connections (up from the previous 2) that is only 3.34 users per second. Drop the keep alive to 1 second and you can handle 50 users per second. These numbers are unrealistic because they assume the request handling itself takes no time at all, but a lot of requests can be handled in split seconds so maybe these numbers aren't so far fetched. If the request handling takes 250ms and you turn keep alive off you could handle 200 users per second.
I am thinking that it would be great to have a reverse proxy sat in front of Apache, one that used an event queue and thus had little memory overhead for maintaining incoming connections, but closed down its connection to Apache after each request. Unfortunately I do not know of one.
So for now is it better to have a 1 second keep alive, or have I missed something?
Jim