Advanced Apache Memory Optimization: Solving High RAM Usage on 4GB Servers


2 views

What you're experiencing is a classic memory leak scenario in Apache. The key indicators are:

  • Steady memory increase despite stable traffic
  • No memory release after requests complete
  • Eventually leads to server crashes

For a 4GB server, let's start with these fundamental settings in httpd.conf:


StartServers 2
MinSpareServers 2
MaxSpareServers 5
MaxClients 10
MaxRequestsPerChild 300

Your current setup appears to be using prefork. Consider switching to worker MPM for better memory efficiency:


<IfModule mpm_worker_module>
    ServerLimit 4
    StartServers 2
    MaxClients 10
    MinSpareThreads 25
    MaxSpareThreads 75
    ThreadsPerChild 25
    MaxRequestsPerChild 0
</IfModule>

If you're running PHP with Apache, these php.ini adjustments help:


memory_limit = 64M
max_execution_time = 30
realpath_cache_size = 128k

Install mod_status for real-time monitoring:


<Location /server-status>
    SetHandler server-status
    Require host localhost
</Location>

Then access via http://localhost/server-status

Create a cron job to automatically restart Apache when memory exceeds 3GB:


#!/bin/bash
THRESHOLD=3000000
APACHE_MEM=$(ps -ylC apache2 | awk '{mem += $8} END {print mem}')

if [ $APACHE_MEM -gt $THRESHOLD ]; then
    /etc/init.d/apache2 restart
fi

For persistent issues, consider:

  • Implementing a reverse proxy with Nginx
  • Moving static content to CDN
  • Using PHP-FPM instead of mod_php

Enable detailed logging to identify memory-heavy requests:


LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-agent}i\" %D %k" debug_log
CustomLog /var/log/apache2/debug.log debug_log


From your top output, I can see each Apache process is consuming ~322MB of virtual memory, with ~37MB resident. Your calculation approach is correct but needs refinement:


# More precise MaxClients calculation:
Total Available RAM = 4000MB
OS/Other Services = 1000MB (estimated)
Available for Apache = 3000MB
Per-process RAM = 37MB (RES column)

MaxClients = 3000/37 ≈ 80

For a 4GB server running prefork (common for PHP environments), try these httpd.conf settings:


StartServers        5
MinSpareServers     5
MaxSpareServers    10
MaxClients        50  # Conservative starting point
MaxRequestsPerChild 1000  # Helps prevent memory leaks

If you're using worker/event MPM (common for modern setups):


ServerLimit         16
StartServers        2
MaxClients        400
MinSpareThreads    25
MaxSpareThreads    75
ThreadsPerChild    25
MaxRequestsPerChild 10000

Your update about growing memory usage suggests either:

  1. PHP memory leaks (common with poorly written extensions/plugins)
  2. Apache module issues (try disabling unused modules)

Debug steps:


# Monitor PHP memory usage:
<?php
memory_get_peak_usage(true)/1024/1024 . "MB\n";
?>

# Apache module cleanup:
apachectl -t -D DUMP_MODULES
# Disable unnecessary modules like mod_rewrite if unused

When Apache starts swapping, performance tanks. Add this to prevent:


# In /etc/sysctl.conf
vm.swappiness = 1
vm.overcommit_memory = 1

For WordPress on 4GB RAM:


# .htaccess memory limit
php_value memory_limit 128M

# httpd.conf additions
<IfModule prefork.c>
    StartServers        3
    MinSpareServers     5
    MaxSpareServers    10
    MaxClients        30
    MaxRequestsPerChild 500
</IfModule>

Remember to restart Apache after changes and monitor with:


watch -n 1 "ps -ylC apache2 --sort:rss | awk '{print $8}'"