Tag: mpm
Apache Performance Tuning: MPM Directives
General Optimization
IfModule
An important directive to learn when working with Apache servers is the IfModule conditional statement. There are two parts to the IfModule statement. A beginning, which also accepts a module name or module source file name, as well as a closing statement. When the provided module is loaded into Apache, then all directives between the beginning IfModule statement and the closing IfModule statement are also read into the Apache running configuration. Please review the provided example below for further clarification:<ifModule mpm_prefork_module>
MaxSpareServers 16
</ifModule>
Timeout 60
The above example defines the MaxSpareServers directive only when loaded by mpm_prefork_module. The Timeout directive is applied every time due to it being outside of the IfModule closing statement.
IfModule statements are used to maintain compatibility within Apache configuration between module changes. Maintaining compatibility is done by grouping directives into IfModule statements, so they are only used when the required module is loaded. Ensuring a syntactically correct configuration file even when swapping modules.
Timeout
The numerical value of seconds Apache waits for all common I/O events. Apache will abandon requests fail to complete before the provided Timeout value. Determining the right Timeout depends on both traffic habits and hosted applications. Ideally, Timeout should be as low as possible while still allowing the vast majority of regular traffic to operate without issue. Large timeouts, those above 1 minute, open the server to SlowLoris style DOS attacks and foster a long wait in the browser when it encounters a problem. Lower timeouts allow Apache to recover from errant stuck connections quickly. It becomes necessary to strike a balance between the two extremes.KeepAlive

MaxKeepAliveRequests
Sets a limit on the number of requests an individual KeepAlive connection is permitted to handle. Once reached, Apache forces the connection to terminate, and creates a new one for any additional requests. Determining an ideal setting here is open to interpretation. Generally, you want this value to be at least as high as the largest count of elements (HTML, Text, CSS, Images, Etc..) served by the most heavily trafficked pages on the server.
KeepAliveTimeout
This directive is measured in seconds and will remain idle waiting for additional requests from its initiator. Since these types of connections are only accessible to their initiator, we want to keep KeepAliveTimeout very low. A low value prevents too many KeepAlive connections from locking out new visitors due to connection priority.MPM Event/Worker Optimization
This section details the use and performance considerations that are essential when running Worker based MPMs, including both MPM Event and MPM Worker. These MPMs are considered multi-threaded solutions and some directives behave differently based on the loaded MPM. The information provided in this section is only a portion about Worker based MPMs.MPM Worker and MPM Event
The two modules, MPM Event, and MPM Worker for most intents and purposes operate identically. The difference is apparent in the way each handles KeepAlive requests. The MPM Worker locks threads for the duration of the KeepAlive process and directly affects the number of available threads able to handle new requests. The MPM Event uses a Listener thread for each child. These Listener threads handle standard requests, and KeepAlive requests alike meaning thread locking will not reduce the capacity of the server. Without thread locking, MPM Event is the superior choice but only in Apache 2.4. Before Apache 2.4 the MPM Event was unstable and prone to problems.ServerLimit
ServerLimit represents the upper limit of children Apache is allowed. The practical usage for ServerLimit is creating a hard ceiling in Apache to protect against input errors with MaxRequestWorkers. The cap prevents spawning vastly more children than a system can handle, resulting in downtime, revenue loss, reputation loss or even data loss.
ThreadsPerChild
Used to define the limit of threads that each Apache child can manage. Every thread running can handle a single request. The default of 25 works well for most cases and is a fair balance between children and threads.

- A memory-heavy shared server hosting numerous independent accounts might opt for a lower ThreadsPerChild, reducing the potential impact of one user affecting another.
- A dedicated Apache server in a high capacity load balanced configuration can choose to increase ThreadsPerChild significantly for a better overall performance of each thread.
ThreadLimit
Used to set the maximum value of ThreadsPerChild. This directive is a hard ceiling for ThreadsPerChild. It helps protect against typographical errors with the
MaxRequestWorkers / MaxClients
The directive sets the limit for active worker threads across all running children and acts as a soft ceiling with ServerLimit taking control as the hard limit. When the number of total running threads has reached or exceeded MaxRequestWorkers, Apache no longer spawns new children.

MinSpareThreads
The least number of Threads that should remain open, waiting for new requests. MinSpareThreads is a multiple of ThreadsPerChild and cannot exceed MaxSpareThreads, though it can match it.
MaxSpareThreads
This directive governs the total number of idle threads allowed on the server across all children. Any threads above this limit direct their parent to shut down to reduce memory consumption during off-peak hours.
StartServers
This directive governs the initial amount of children the Apache Parent process spawns when the Apache service is started or restarted. This is commonly left unchanged since Apache continuously checks the current running children in conjunction with ThreadsPerChild and compare it to MinSpareThreads to determine if more children get forked. This process is repeated perpetually, with a doubling of new children on each iteration, until MinSpareThreads is satisfied.
MaxConnectionsPerChild / MaxRequestsPerChild
The number of requests a single Apache child process can handle equals a cumulative total on the child server across all threads it controls. Each request handled by a thread counts toward this limit to its parent. Once the child server has reached its limit, the child is then recycled. This directive is a stop-gap for accidental memory leaks. Some code executed through Apache threads may contain memory leaks. Leaked memory are portions of memory that subprocess failed to release properly, so they are inaccessible to any outside processes. The longer a leaking program is left running, the more memory it will leak. Setting a MaxConnectionsPerChild limit is a specific method for assuring Apache is periodically recycling programs to reduce the impact of leaked memory on the system. When using external code handlers like Mod_fcgid, PHP-FPM or mod_lsapi, it becomes necessary to set MaxConnectionsPerChild to 0 (unlimited), doing so prevents periodic error pages caused by Apache terminating threads prematurely.MPM Prefork Optimization
This MPM Prefork section details the use and performance considerations for various directives when running this module. This MPM is a non-threaded multi-processor designed for compatibility. It consists of a single Apache parent process, which is used to govern all new Apache processes also known as children. The following directives show how Apache is capable of performance tuning when using MPM Prefork. Unlike Worker based MPMs, optimizing MPM Prefork is generally simple and straightforward. There is a 1:1 ratio of Apache processes to incoming requests. However, MPM Prefork does not scale well with hardware and the more traffic it encounters, the more hardware it will need to keep up with the pace. It should be noted that some directives behave differently based on which MPM is loaded. The information provided in this section is only the portion about MPM Prefork.MaxRequestWorkers / MaxClients
Used to control the upper limit of children that the Apache parent server is allowed to have in memory at one time. These children (also called workers) handle requests on a 1:1 ratio. This translates into the maximum number of simultaneous requests the server can handle.
MinSpareServers
This directive defines a minimum number of spare children the Apache parent process can maintain in its memory. An additional server is a preforked idle Apache child that is ready to respond to a new incoming request. Having idle children waiting for new requests is essential for providing the fastest server response times. When the total idle children on the server drop below this value, a new child is preforked at the rate of one per second until this directive is satisfied. The “one per second” rule is in place to prevent surges of the creation process that overload the server, however, this failsafe comes at a cost. The one per second spawn rate is particularly slow when it comes to handling page requests. So it’s highly beneficial to make sure enough children are preforked and ready to handle incoming requests.MaxSpareServers
MasSpareServers controls the maximum number of idle Apache child servers running at one time. An idle child is one which is not currently handling a request but waiting for a new request. When there are more than MaxSpareServers idle children, Apache kills off the excess. If the MaxSpareServers value is less than MinSpareServers, Apache will automatically adjust MaxSpareServers to equal MinSpareServers plus one. Like with MinSpareServers, this value should always be altered with available server resources in mind.StartServers
Created at startup, are the initial amount of Apache child servers. This seldom changed directive only impacts Apache startup and restart processes. Generally not altered because Apache uses internal logic to work out how many child servers should be running. Many modern servers periodically restart Apache to address configuration changes, rotate log files or other internal processes. When this occurs during a high load traffic surge, every bit of downtime matters. You can manually set the StartServers directive to mirror that of your MinSpareServers to shave off time from the Apache startup.
ServerLimit
The ServerLimit directive represents the upper limit of MaxRequestWorkers. This setting is generally used as a safeguard or ceiling against input errors when modifying MaxRequestWorkers.

MaxConnectionsPerChild / MaxRequestsPerChild
This directive equals the number of requests a single Apache child server can handle. This directive is a stop-gap for accidental memory leaks. Code executed through Apache may contain faults which leak memory. These leaks add up over time making less and less of the shared memory pool of the child usable. The way to recover from leaked memory is to recycle the affected Apache child process. Setting a MaxConnectionsPerChild limit will protect from this type of memory leakage.Apache Performance Tuning: MPM Modules
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 Liquid Web Linux based VPS servers. These modules are:
MPM Prefork
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 serverpool. 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.
MPM Worker
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 make for both a high capacity and low resource solution for web service.
MPM Event
Based off 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 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.

Other MPMs
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.
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. Or check out our previous article in this series, Apache Performance Tuning: Swap Memory.