Apache MPM Comparison: Prefork vs Worker – Performance, Use Cases and Configuration Guide for Developers


2 views

Apache's Multi-Processing Modules (MPMs) fundamentally differ in their process handling approaches:

# Prefork MPM uses multiple child processes with one thread each
StartServers        5
MinSpareServers     5
MaxSpareServers    10
MaxClients        150
MaxRequestsPerChild  0

# Worker MPM uses multiple child processes with multiple threads each
StartServers        2
MaxClients        150
MinSpareThreads    25
MaxSpareThreads    75
ThreadsPerChild    25
MaxRequestsPerChild  0

Prefork MPM:
- Memory-intensive (each connection = separate process)
- More stable for PHP applications (no shared memory issues)
- Better isolation between requests

Worker MPM:
- Lower memory footprint (threads share memory space)
- Higher concurrent connection capacity
- Potential threading issues with non-thread-safe libraries

Prefork is preferable when:
- Running PHP with mod_php (not thread-safe)
- Using older Apache modules not optimized for threading
- Stability is more critical than raw performance

Worker shines when:
- Serving static content at high volumes
- Using event-driven architectures
- Running thread-safe applications (like Python WSGI)

Optimizing Prefork for memory-heavy applications:

<IfModule mpm_prefork_module>
    StartServers           8
    MinSpareServers        5
    MaxSpareServers       20
    ServerLimit          256
    MaxClients           256
    MaxRequestsPerChild 4000
</IfModule>

Tuning Worker for high-throughput scenarios:

<IfModule mpm_worker_module>
    StartServers           4
    MaxClients           300
    MinSpareThreads      25
    MaxSpareThreads      75
    ThreadsPerChild      25
    MaxRequestsPerChild   0
</IfModule>

When switching between MPMs, always:

  1. Back up current configuration
  2. Verify module dependencies (e.g., php-zts for threaded PHP)
  3. Test with production-like traffic patterns
  4. Monitor memory usage during transition

Worker MPM problems often manifest as:
- Segmentation faults in non-thread-safe libraries
- Memory leaks in long-running threads
- Race conditions in shared resources

Prefork issues typically include:
- High RAM consumption under load
- Slower response times during traffic spikes
- Process creation overhead


The fundamental distinction lies in their process/thread handling:

  • Prefork MPM: Uses multiple child processes with one thread each
  • Worker MPM: Uses multiple child processes with multiple threads each
# Sample configuration differences
# Prefork MPM
<IfModule mpm_prefork_module>
    StartServers          5
    MinSpareServers       5
    MaxSpareServers      10
    MaxClients          150
    MaxRequestsPerChild   0
</IfModule>

# Worker MPM
<IfModule mpm_worker_module>
    StartServers          2
    MinSpareThreads      25
    MaxSpareThreads      75
    ThreadLimit          64
    ThreadsPerChild      25
    MaxClients          150
    MaxRequestsPerChild   0
</IfModule>

Benchmark data shows:

Metric Prefork Worker
Memory Usage Higher (20-30MB per process) Lower (shared memory between threads)
Concurrent Connections Limited by RAM Handles more efficiently
Static Content Faster (~5% benchmarks) Slower due to threading overhead

Choose Prefork when:

  • Running PHP with mod_php (not thread-safe)
  • Using non-thread-safe libraries
  • Memory isn't a constraint

Choose Worker when:

  • Using FastCGI (PHP-FPM)
  • Need better scaling for many concurrent connections
  • Running on memory-constrained servers

Switching from Prefork to Worker:

# Stop Apache
sudo service apache2 stop

# Install Worker MPM
sudo apt-get install apache2-mpm-worker

# Verify active MPM
apache2ctl -V | grep -i mpm

# Adjust thread settings in /etc/apache2/mods-available/mpm_worker.conf
ThreadsPerChild 25
MaxRequestWorkers 150

# Restart
sudo service apache2 start

Prefork success case: Legacy application using mod_php with custom extensions that aren't thread-safe. Memory usage stayed under 4GB on a dedicated server.

Worker success case: High-traffic WordPress site using PHP-FPM, handling 2,000+ concurrent users on a 8GB VPS with optimized thread settings.

Common Worker MPM issues and solutions:

# Debug threading issues
strace -f -p $(pgrep apache2)

# Check for memory leaks
watch -n 1 "ps -ylC apache2 --sort:rss"

# Monitor thread activity
apachetop -f /var/log/apache2/access.log

For Worker MPM tuning:

# Calculate optimal ThreadsPerChild
Total RAM - OS overhead = Available RAM
Available RAM / Process size = MaxClients
MaxClients / ThreadsPerChild = ServerLimit

Example for 8GB server:
8GB - 1GB = 7GB available
7GB / 20MB per process = 350 MaxClients
350 / 25 threads = 14 ServerLimit