May 10, 2008

Apache2 Worker MPM on Low Memory Servers

If you're running Apache2 on a memory-constrained system (like in a virtual machine,) you may want to choose the prefork MPM to save memory at the cost of more process forks. However, if you have more than one CPU on that same machine, you may also want to consider using the threaded worker MPM and tweak its MaxClients and ThreadsPerChild settings from the default configuration.

On a typical apache2 installation on a Debian system, the worker MPM configuration looks like this:

<IfModule mpm_worker_module>
    MaxClients          150
    MinSpareThreads      25
    MaxSpareThreads      75
    ThreadsPerChild      25
    MaxRequestsPerChild   0
</IfModule>

Using these default settings on a resource-constrained system (say a server with 128MB of RAM but with no swap) would be overkill, and the web server processes will definitely eat up all of that memory, leaving little or no room for even simple CGI scripts.

In my setup, I experimented with tweaking the values above to get apache2 to serve without eating up too much precious memory. I found that the important values to consider here are MaxClients, which dictate how many clients can connect simultaneously to my server, and ThreadsPerChild, which specifies how many threads of execution can run in a child/worker process. My resulting config becomes:

<IfModule mpm_worker_module>
    MaxClients           15
    MinSpareThreads       3
    MaxSpareThreads       7
    ThreadsPerChild       3
    MaxRequestsPerChild 200
</IfModule>

With this setup, I free up a significant amount of RAM from apache2's hold whle maximizing my thread usage in each worker process; at the same time, I avoid keeping each child process for too long by setting a maximum number of requests each worker can serve, preventing the workers to bloat too much when handling CGI.

I also tweaked the KeepAliveTimeout setting to just 2 seconds (instead of the default 15) so that each worker process can go to the next request quickly and preventing them from being tied up to a connection for too long. I also set the Timeout to 30 seconds.

Tags: , , , . | Posted at: 10:42 | 2 Comments/Trackbacks.

Eric Covener wrote at 2008-05-12 08:28:

For worker, MinSpareThreads and MaxSpareThreads should both be multiples of ThreadsPerChild otherwise rounding is being done on your behalf.

Worker will start/kill 1 process, containing ThreadsPerChild children, when load dictates -- it can't ever zap or add a single thread.

You might also want to look at ThreadStackSize directive and move to a single child process with 15 threads.

Zak B. Elep wrote at 2008-05-12 18:40:

Hi Eric! Thanks for the comment!

I followed your tip on looking into ThreadStackSize. I reduced my setting down to 65536 bytes and was able to bring down my apache2 process usage from 50MB to just 10MB! And it works quite well with little to no effect on the speed of requests handled!


Leave a Comment

Name:
URL (optional):
Comments:

URL for TrackBack pings: http://blog.zakame.net/tips/apache2-worker-lowmem/trackback