The keystone for understanding Apache server performance is by far the Multiprocessing Modules (MPMs). These modules determine the basis for how Apache addresses multiprocessing. Multiprocessing means running multiple operations simultaneously in a system with multiple central processing units (CPU Cores).
There are many MPMs to choose from; however, this article focuses on the most commonly used modules found in Linux-based VPS servers. These modules are:
- MPM Prefork
- MPM Worker
- MPM Event
- Other MPMs
The self-regulating MPM Prefork derives its namesake from how it forks or copies itself into new identical processes preemptively to wait for incoming requests. A non-threaded process-based approach at multiprocessing, MPM Prefork runs Apache in a single master parent server process. This parent is responsible for managing any additional child servers that make up its server pool. While using MPM Prefork, each child server handles only a single request. This focus provides complete isolation from other requests dealt with on the server. MPM Prefork is typically used for compatibility when non-threaded libraries/software, like mod_php (DSO), are required. From an optimization standpoint, MPM Prefork can be sorely lacking when compared to multi-threaded solutions, requiring vastly more resources to reach similar traffic levels as a threaded MPM. It is resource-intensive due to its need to spawn full copies of Apache for every request.
Avoid using MPM Prefork whenever possible. Its inability to scale well with increased traffic will quickly outpace the available hardware on most system configurations.
A hybrid pre-forking, multi-threaded, multiprocessing web server. In the same fashion as MPM Prefork, MPM Worker uses the same approach with a single master parent process governing all children within its server pool. However, unlike MPM Prefork, these children are multi-threaded processes that can handle dozens of threads (requests) simultaneously. MPM Worker has set the foundation for multi-threaded multiprocessing in Apache servers which became stable in Apache 2.2. The threaded configuration allows Apache to service hundreds of requests with ease while retaining only a dozen or so child processes in memory. The MPM Worker makes for both a high capacity and low resource solution for web service.
The KeepAliveTimeOut directive currently defines the amount of time Apache will wait for requests. When utilizing KeepAlive with MPM Worker use the smallest KeepAliveTimeout as possible (1 second preferably).
Based on the MPM Worker source code, MPM Event shares configuration directives with MPM Worker. It works nearly identical to MPM Worker except when it comes to handling KeepAlive requests. MPM Event uses a dedicated Listener thread in each child’s process. This Listening thread is responsible for directing incoming requests to an available worker thread. The Listening thread solves the issue encountered by MPM Worker which locks entire threads into waiting for the KeepAliveTimeout. The Listener approach of MPM Event ensures worker threads are not “stuck” waiting for KeepAliveTimeout to expire. This method keeps the maximum amount of worker threads handling as many requests as possible.
MPM Event is stable in Apache 2.4, older versions can use MPM Worker as an alternative.
There is an assortment of additional MPMs available. These are typically part of Apache’s integration into Operating Systems other than Unix-based systems. These have specific MPMs which are requirements or utilizing Apache on their respective system types. These types of MPMs are beyond the purview of this article. You can find more information on specific MPM in the MPM Defaults section of the official Apache Documentation.
I recommend staying away from experimental and unstable MPMs. The unreliable nature of these types of software renders them unsupportable.
Which MPM is the best?
When considering optimization, it is essential to understand there is no such thing as a one-size-fits-all Apache configuration. Correctly choosing an MPM requires analysis of many moving variables like traffic, site code, server type, PHP Handler, and available hardware. Every server is unique making the best MPM an entirely subjective choice.
If your application code does not support multi-threading, then your choice will inevitably be MPM Prefork purely on a compatibility basis. MPM Prefork includes software modules like mod_php (DSO). MPM Worker without KeepAlive performs very well if your application is a high-performance load-balanced API system. The scalability and flexibility of MPM Event is a solid choice for hosting multiple small to medium sites in a shared hosting configuration.
Most simple servers setups operate well under the self-governing default configuration of MPM Event, making it an ideal starting point for optimization tuning. Once chosen, an MPM can then move onto Configuration Directives to review which settings pertain to server performance and optimization.