Apache MPM Selection Guide: worker vs. event vs. prefork Performance Comparison


4 views

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