Apache's Multi-Processing Modules (MPMs) determine how HTTP requests are handled at the server level. The three primary MPMs in modern Apache deployments are:
# Check current MPM on Linux:
apache2ctl -V | grep -i mpm
# Sample output:
Server MPM: event
Prefork MPM (non-threaded):
- Uses multiple child processes with one thread each
- Process isolation provides stability
- Memory-heavy due to process duplication
Worker MPM (hybrid):
<IfModule mpm_worker_module>
StartServers 2
MinSpareThreads 25
MaxSpareThreads 75
ThreadLimit 64
ThreadsPerChild 25
MaxRequestWorkers 150
MaxConnectionsPerChild 0
</IfModule>
Event MPM (asynchronous):
- Enhanced version of worker MPM
- Uses dedicated listener threads for keep-alive connections
- Better for high-traffic HTTPS sites
AWS t3.medium benchmark results (Apache 2.4):
MPM | Req/sec | Memory | Keep-alive |
---|---|---|---|
Prefork | 1,200 | High | Poor |
Worker | 3,800 | Medium | Good |
Event | 4,500 | Medium | Excellent |
For PHP applications using mod_php:
# Requires prefork MPM
sudo a2dismod mpm_event
sudo a2enmod mpm_prefork
sudo systemctl restart apache2
For modern applications with PHP-FPM:
# Optimal with event MPM
sudo a2dismod mpm_prefork
sudo a2enmod mpm_event proxy_fcgi
sudo systemctl restart apache2
When seeing "MPM not supported" errors:
# Check compiled modules:
apache2 -l
# Verify module compatibility:
apache2ctl -M | grep mpm
Apache HTTP Server offers different Multi-Processing Modules (MPMs) that determine how the server handles incoming requests. The choice of MPM significantly impacts performance, especially under different workloads. The three main MPMs are:
- Prefork: Process-based model (one process per connection)
- Worker: Hybrid model (threads within processes)
- Event: Asynchronous model (improved version of Worker)
Here's a technical breakdown of each MPM's architecture:
# Prefork MPM configuration example
<IfModule mpm_prefork_module>
StartServers 5
MinSpareServers 5
MaxSpareServers 10
MaxRequestWorkers 150
MaxConnectionsPerChild 0
</IfModule>
# Worker MPM configuration example
<IfModule mpm_worker_module>
StartServers 3
MinSpareThreads 75
MaxSpareThreads 250
ThreadsPerChild 25
MaxRequestWorkers 400
MaxConnectionsPerChild 0
</IfModule>
# Event MPM configuration example
<IfModule mpm_event_module>
StartServers 3
MinSpareThreads 75
MaxSpareThreads 250
ThreadsPerChild 25
MaxRequestWorkers 400
MaxConnectionsPerChild 0
</IfModule>
Prefork is the safest choice when:
- Running non-thread-safe modules (like mod_php)
- Dealing with legacy applications
- Needing maximum stability over performance
Worker is ideal when:
- Using thread-safe modules (like mod_wsgi)
- Handling static content or reverse proxying
- Needing better performance than Prefork
Event is best for:
- High-performance serving of static content
- Handling many concurrent connections (keep-alive)
- Modern deployments with thread-safe modules
Benchmarking different MPMs with ApacheBench:
# Benchmark command example
ab -n 10000 -c 100 http://yourserver/test.html
# Typical results (requests per second):
# Prefork: ~1500
# Worker: ~3500
# Event: ~4500
To change MPMs on Debian/Ubuntu:
# Disable current MPM
sudo a2dismod mpm_prefork
# Enable new MPM
sudo a2enmod mpm_event
# Restart Apache
sudo systemctl restart apache2
Use mod_status to monitor your MPM's performance:
# Enable mod_status
<Location "/server-status">
SetHandler server-status
Require host example.com
</Location>
# Then access:
http://yourserver/server-status
If you encounter "mpm_worker: error" messages, check:
- Thread-safe versions of all modules
- Sufficient system resources (ulimit -n)
- Proper MaxRequestWorkers setting