The first step is to determine which MPM (Multi-Processing Module) your Apache installation is actually using. On Debian systems, you can check this with:
apache2ctl -V | grep -i mpm
If you're not seeing any MPM modules in mods-available
or mods-enabled
, it's likely you're using the default prefork
module, which is common for older systems and PHP applications.
With only 448MB RAM, we need to be extremely conservative. A good rule of thumb is to allocate:
- ~100MB for OS overhead
- ~50MB for other services
- Leaving ~300MB for Apache
Each Apache process in prefork typically uses 10-20MB. So we should aim for no more than 15-20 total processes.
For your mpm_prefork_module
, try these settings:
StartServers 2
MinSpareServers 2
MaxSpareServers 5
MaxClients 15
MaxRequestsPerChild 1000
- StartServers 2: Begin with just 2 processes to conserve memory
- MinSpareServers 2: Keep minimum spare processes low
- MaxSpareServers 5: Prevent too many idle processes
- MaxClients 15: Hard limit to stay within memory constraints
- MaxRequestsPerChild 1000: Recycle processes periodically to prevent memory leaks
Consider adding these to your configuration:
# Reduce keepalive settings
KeepAlive Off
# Or if you must have it:
KeepAlive On
KeepAliveTimeout 2
MaxKeepAliveRequests 50
# Disable unneeded modules
# Example:
# a2dismod auth_basic authn_file authz_default authz_groupfile authz_user autoindex
Install and configure apachetop
to monitor in real-time:
sudo apt-get install apachetop
apachetop -f /var/log/apache2/access.log
For process-level monitoring:
watch -n 5 "ps -ylC apache2 --sort:rss | head -20"
If you're still having memory issues:
- Switch to
lighttpd
ornginx
which are lighter - Implement a cron job to gracefully restart Apache nightly
- Upgrade to a more modern lightweight distro like Alpine Linux
The first critical step is determining which Multi-Processing Module (MPM) your Apache instance is actually using. On Debian systems, run:
apache2 -V | grep -i mpm
# Example output:
# Server MPM: prefork
With only 448MB RAM available (shared with OS and other services), we need aggressive optimization:
# Formula for MaxClients in prefork:
MaxClients ≈ (Total RAM - (OS + other services)) / Average Apache process size
# For a typical 30MB Apache process:
(448 - 100) / 30 = ~11 MaxClients
StartServers 2
MinSpareServers 2
MaxSpareServers 4
MaxClients 10
MaxRequestsPerChild 1000
StartServers 1
MinSpareThreads 10
MaxSpareThreads 20
ThreadLimit 20
ThreadsPerChild 10
MaxClients 20
MaxRequestsPerChild 1000
- Enable KeepAlive with short timeout:
KeepAliveTimeout 2
- Reduce timeout:
Timeout 30
- Disable unused modules:
a2dismod autoindex status
# Check memory usage:
ps -ylC apache2 --sort:rss | head -10
# Real-time monitoring:
watch -n 1 "free -m && echo '' && ps -eo pid,user,comm,pmem --sort -pmem | head -5"