Apache MPMs

From Helpful
Jump to: navigation, search
Related to web development, hosting, and such: (See also the webdev category)
jQuery: Introduction, some basics, examples · plugin notes · unsorted

Server stuff:

Dynamic server stuff:

This article/section is a stub — probably a pile of half-sorted notes, is not well-checked so may have incorrect bits. (Feel free to ignore, fix, or tell me)

MPM notes

MPM carries the meaning of 'the module that manages the handling of many requests'. A bunch of different setups exist (as you can write your own) but there are only a few that are interesting/relevant.

MPMs can use multiple processes, multiple threads, or both. The best choice depends on your environment (does the OS support forking), code (e.g. threadsafeness), and other requirements.

to avoid confusion with the worker MPM, the word 'actor' is used (instead of 'worker') below in the meaning of 'thing that can handle a request'. Most actors handle many requests over their lifetime, mostly to lower latencies (exceptions include CGI)


Most MPMs can create a configurable amount of fixed/total/spare/idle processes or threads, because starting them when things are idle means that when a request comes in it can be immediately assigned, and the latency of actor startup can be avoided (...for as long as there are still idle actors; at some level of heavy load there's just no time).

You can configure that it would spawn more at busy times, and reduce the number when many become idle.


Non-threaded MPMs include:

  • prefork [1]
    • multiple processes, each process is a single actor (handles one request at a time)
    • uses forking to make process startup simpler).
    • not available on windows (because fork() is not)
    • starts at most min(MaxClients,ServerLimit)(verify) children
    • for the same amount of actors, it will use more memory than threaded MPMs, because each process has some base memory and its own loaded copy of modules.
  • itk, a derivative of prefork that allows running different vhosts as different users.


Threaded/hybrid MPMs (hybrid means multiple processes, each multithreaded) include:

  • worker
    • hybrid: multi-threaded in multiple processes
    • Regularly seen as the main alternative to prefork when you want threading and more actors.
    • ...typically meaning less memory use and less CPU overhead
    • Not every module is written for multithreaded use. Perhaps one of the most significant is PHP
  • event
    • derivative of worker
    • dedicates a thread for a request, rather than a thread for a connection (better behaved around keepalive, fewer threads sitting around waiting on an idle connection)
    • experimental (introduced in 2.4), but seems to work well, and can be faster than worker with less configuration worry


  • winnt [2]
    • Default on windows
    • multi-threaded in a single process.
    • ...so like worker, but limited to a single process that shares all threads. This also means that the one process is not killed unless apache is restarted, a persistence that can be useful as well as bite you)
  • beos [4]
    • single control process creating threads for requests
  • leader (experimental)
    • variant of worker;
  • threadpool (experimental)
    • variant of worker (Not as interesting as worker)
  • perchild (experimental)
    • not currently functional (you probably want worker)
    • multi-threaded in multiple processes


Default MPMs:

  • Most unices: prefork
  • BeOS, Netware, and OS/2 use their own (beos, mpm_netware, mpmt_os2).
  • Windows: mpm_winnt


Which MPM am I using?

Run:

apache2 -V

Which will mention something like:

Server MPM:     Worker
  threaded:     yes (fixed thread count)
    forked:     yes (variable process count)

Some notes

Slow running actors means delays

...one way or another. If it's waiting on CPU or IO-bound work, then the server can't go faster. Allowing more actors to run won't help - sure, you can start the work for more people, but they'll finish slower so no one will be served any faster.

If that time is not all CPU, or if you can avoid CPU or IO (particularly using caching; memory is a relatively cheap resource) then you should - it'll be good for resources (CPU and IO), the request rate, and so general snappiness.


On amount of actors, and implied memory

This article/section is a stub — probably a pile of half-sorted notes, is not well-checked so may have incorrect bits. (Feel free to ignore, fix, or tell me)

A few dozen actors is enough. In theory, just a handful can saturate your resources, but depending on the work they do, there may be waiting involved, so a dozen or two is often configured to ensure your CPU/IO resources are being used pretty well.


There are few upside in having more, and a number of possible downsides (such as swapping when memory usage peaks over available RAM).


You usually want to limit the amount of processes, to limit their potential memory use.

Perhaps a few dozen processes per GB of typically available RAM is fair.

You can expect each apache prefork-style process (with various basic modules and PHP) to have on the order of ~10-15MB of basic memory use. You can sometimes slim it down, and it can be much more bloated with a lot of of modules - and with applications allocating/handling lots of data.


Multithreaded and hybrid MPMs have most of the overhead just once, so use much less memory per actor than prefork. For example, you may find a 20-thread process using 35MB, which (uneducated guess)might be ~15MB of overhead and ~1MB per thread.

This makes them an interesting way of ensuring you can handle a lot of requests at once, while knowing memory scarcity won't become a problem under load. That's usually also the only immediate upside, because until memory is a problem, your apps are probably IO-bound or CPU-bound.


For example, a setup with 20 processes and 20 threads each is fairly pointless. If you actually have 400 concurrent page serves, you're still just dividing CPU time between them. Even assuming you have a 12-core CPU, that means 33 concurrent processes on each, probably meaning each will take about 30 times as long as they would if alone on that core. Users are not being served any faster. And you may be decimating IO performance.


Note that some modules may allocate a bunch of RAM but never use it. This means a large number of actors will need to be able to map a lot of memory, but will never use it. For this reason, it may be interesting to configure swap space on a server so that that memory can be mapped, even if it will never be allocated.