Tech machine

Zak B. Elep: Apache2 Worker MPM on Low Memory Servers

Maggio 10, 2008Nat0 Comments

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

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

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

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

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.