An Apache MPM (Multi-Processing Module) decides how Apache accepts connections and hands them to processes or threads. Exactly one MPM is active at a time, and the choice affects memory use, concurrency and which PHP handlers work. This guide explains prefork, worker and event and shows how to switch and tune them.
Before you start
- A Linux VPS with Apache 2.4 and root access.
- Know how PHP is run: mod_php or PHP-FPM. See application servers explained.
Check which Apache MPM is active
apachectl -V | grep -i mpmOn Debian/Ubuntu you can also run a2query -M.
Prefork: one process per connection
Prefork starts a pool of single-threaded child processes. Each child handles one connection at a time. It is the only MPM that works with mod_php, because older PHP extensions are not thread-safe.
- Pros: simple, isolates crashes, works with non-thread-safe code.
- Cons: each child carries a full copy of PHP, often 30–80 MB, so concurrency is limited by RAM. Idle keep-alive connections tie up whole processes.
Worker: threads inside processes
Worker runs several processes, each with many threads. One thread serves one connection. Memory per connection is much lower than prefork. The weakness: a thread waiting on an idle keep-alive connection still counts as busy.
Event: worker plus a keep-alive listener
Event is worker with a dedicated listener thread that parks idle keep-alive and lingering-close connections. Threads are only used while a request is actually being processed, so thousands of open connections need far fewer threads. Event is the default on modern distributions and the right choice when PHP runs through PHP-FPM.
Which Apache MPM should you use?
| MPM | Concurrency model | PHP handler | Use when |
|---|---|---|---|
| prefork | Process per connection | mod_php | Legacy apps that need mod_php |
| worker | Thread per connection | PHP-FPM | Rarely; event is better |
| event | Thread per active request | PHP-FPM | Almost every modern server |
Switch from prefork to event
- Install PHP-FPM and the proxy module:
sudo apt install php-fpmandsudo a2enmod proxy_fcgi setenvif. - Disable mod_php and prefork, enable event:
sudo a2dismod php8.3 mpm_prefork && sudo a2enmod mpm_event && sudo a2enconf php8.3-fpm - On AlmaLinux/Rocky, edit
/etc/httpd/conf.modules.d/00-mpm.conf, comment the preforkLoadModuleline and uncommentmpm_event_module. PHP-FPM is used there by default. - Test and restart:
sudo apachectl configtest && sudo systemctl restart apache2
Tune the event MPM
Edit /etc/apache2/mods-available/mpm_event.conf (or a file in /etc/httpd/conf.d/):
<IfModule mpm_event_module>
StartServers 2
ServerLimit 8
ThreadsPerChild 25
MaxRequestWorkers 200
MinSpareThreads 25
MaxSpareThreads 75
MaxConnectionsPerChild 10000
</IfModule>MaxRequestWorkers= total threads that can process requests at once. It must be ≤ServerLimit × ThreadsPerChild.- With event and PHP-FPM, Apache threads are light; the real limit is PHP-FPM's
pm.max_children. Size that one against RAM (see PHP-FPM pool tuning). - For prefork, estimate:
MaxRequestWorkers ≈ (RAM for Apache) ÷ (average child RSS). Measure RSS withps -o rss= -C apache2.
Troubleshooting
- "Apache is running a threaded MPM, but your PHP Module is not compiled to be threadsafe": mod_php is still enabled. Disable it and use PHP-FPM.
- Log says "server reached MaxRequestWorkers setting": requests are queuing. Raise the value if RAM allows, or find slow PHP requests holding workers.
- PHP source code shown instead of running: no PHP handler after the switch. Enable the
php-fpmconf andproxy_fcgi.
FAQ: Apache MPM
Is event MPM safe for WordPress?
Yes, with PHP-FPM. WordPress never talks to the MPM directly.
Does LiteSpeed use an MPM?
No. LiteSpeed is event-driven by design and reads Apache configs without using MPMs.
Can I mix MPMs per site?
No. One MPM serves the whole Apache instance.
