Fix Apache web server high memory usage and optimize performance

Beginner 25 min Apr 17, 2026
Ubuntu 24.04 Ubuntu 22.04 Debian 12 AlmaLinux 9 Rocky Linux 9 Fedora 41

Diagnose Apache memory issues and optimize MPM modules, worker processes, and configuration to reduce RAM usage and improve web server performance.

Prerequisites

  • Root access to the server
  • Apache web server installed
  • Basic command line knowledge

What this solves

Apache web servers can consume excessive memory due to misconfigured Multi-Processing Modules (MPM), too many worker processes, or unnecessary modules. This guide helps you diagnose high memory usage, tune MPM settings, disable unused modules, and implement monitoring to keep Apache running efficiently.

Diagnose Apache memory usage

Check current Apache processes

Start by examining how much memory Apache is currently using across all processes.

ps aux | grep apache2 | grep -v grep
ps aux | grep httpd | grep -v grep

Calculate total Apache memory consumption

Get a precise measurement of Apache's total memory footprint using process monitoring tools.

pmap -d $(pgrep apache2) 2>/dev/null | tail -1
pmap -d $(pgrep httpd) 2>/dev/null | tail -1

Monitor memory usage in real-time

Use htop to watch Apache processes and their memory consumption patterns over time.

sudo htop -p $(pgrep -d',' apache2)
sudo htop -p $(pgrep -d',' httpd)

You can also use our comprehensive process monitoring guide for more advanced analysis techniques.

Check Apache configuration and active modules

Identify which MPM module is active and what modules are loaded.

apache2ctl -V | grep -i mpm
apache2ctl -M | head -20
httpd -V | grep -i mpm
httpd -M | head -20

Configure MPM modules for memory optimization

Switch to Event MPM for better memory efficiency

The Event MPM handles more concurrent connections with fewer processes than Prefork MPM, significantly reducing memory usage.

sudo a2dismod mpm_prefork
sudo a2enmod mpm_event
sudo systemctl restart apache2
sudo systemctl stop httpd
sudo dnf install -y httpd-devel
sudo systemctl start httpd

Configure Event MPM parameters

Tune the Event MPM settings based on your server's available memory and expected traffic load.


    StartServers             3
    MinSpareThreads          25
    MaxSpareThreads          75
    ThreadLimit              64
    ThreadsPerChild          25
    MaxRequestWorkers        400
    ServerLimit              16
    AsyncRequestWorkerFactor 2
LoadModule mpm_event_module modules/mod_mpm_event.so


    StartServers             3
    MinSpareThreads          25
    MaxSpareThreads          75
    ThreadLimit              64
    ThreadsPerChild          25
    MaxRequestWorkers        400
    ServerLimit              16
    AsyncRequestWorkerFactor 2

Calculate optimal MaxRequestWorkers

Set MaxRequestWorkers based on available server memory to prevent swap usage.

# Calculate: (Available RAM - Other processes) / Average Apache process size

For a 4GB server with 1GB for other processes:

(3GB * 1024MB) / 25MB per process = ~122 workers

free -m echo "Recommended MaxRequestWorkers: $(($(free -m | awk '/^Mem:/{print $2}') * 3 / 4 / 25))"

Disable unnecessary Apache modules

List all enabled modules

Identify modules that are loaded but not needed for your specific use case.

apache2ctl -M | sort
httpd -M | sort

Disable common unnecessary modules

Disable modules that are commonly enabled by default but rarely used in production.

sudo a2dismod status
sudo a2dismod autoindex
sudo a2dismod negotiation
sudo a2dismod include
sudo systemctl reload apache2
# Comment out these lines:
#LoadModule status_module modules/mod_status.so
#LoadModule autoindex_module modules/mod_autoindex.so
#LoadModule negotiation_module modules/mod_negotiation.so
#LoadModule include_module modules/mod_include.so

Keep only essential modules

Ensure you keep modules required for basic functionality and your specific applications.

Essential modules: mod_mime, mod_dir, mod_rewrite (if using URL rewriting), mod_ssl (for HTTPS), mod_php (if serving PHP), and your chosen MPM module.

Optimize Apache configuration

Configure KeepAlive settings

Tune KeepAlive to reduce connection overhead while preventing connection hoarding.

KeepAlive On
MaxKeepAliveRequests 100
KeepAliveTimeout 2
KeepAlive On
MaxKeepAliveRequests 100
KeepAliveTimeout 2

Set appropriate timeout values

Configure timeouts to prevent processes from hanging and consuming memory indefinitely.

Timeout 30
RequestReadTimeout header=20-40,MinRate=500 body=20,MinRate=500
Timeout 30
RequestReadTimeout header=20-40,MinRate=500 body=20,MinRate=500

Enable compression to reduce bandwidth usage

Configure mod_deflate to compress responses and reduce memory spent on large transfers.

sudo a2enmod deflate
sudo systemctl reload apache2

    AddOutputFilterByType DEFLATE text/plain
    AddOutputFilterByType DEFLATE text/html
    AddOutputFilterByType DEFLATE text/xml
    AddOutputFilterByType DEFLATE text/css
    AddOutputFilterByType DEFLATE application/xml
    AddOutputFilterByType DEFLATE application/xhtml+xml
    AddOutputFilterByType DEFLATE application/rss+xml
    AddOutputFilterByType DEFLATE application/javascript
    AddOutputFilterByType DEFLATE application/x-javascript
LoadModule deflate_module modules/mod_deflate.so


    AddOutputFilterByType DEFLATE text/plain
    AddOutputFilterByType DEFLATE text/html
    AddOutputFilterByType DEFLATE text/xml
    AddOutputFilterByType DEFLATE text/css
    AddOutputFilterByType DEFLATE application/xml
    AddOutputFilterByType DEFLATE application/xhtml+xml
    AddOutputFilterByType DEFLATE application/rss+xml
    AddOutputFilterByType DEFLATE application/javascript
    AddOutputFilterByType DEFLATE application/x-javascript

Implement memory monitoring and alerts

Create memory monitoring script

Set up automated monitoring to track Apache memory usage and alert when thresholds are exceeded.

#!/bin/bash

Apache process names (adjust based on your distribution)

APACHE_PROC="apache2\|httpd"

Memory threshold in MB

MEMORY_THRESHOLD=1000

Calculate total Apache memory usage

TOTAL_MEMORY=$(ps aux | grep "$APACHE_PROC" | grep -v grep | awk '{sum+=$6} END {print sum/1024}') TOTAL_MEMORY=${TOTAL_MEMORY%.*} # Remove decimal if [ "$TOTAL_MEMORY" -gt "$MEMORY_THRESHOLD" ]; then echo "WARNING: Apache using ${TOTAL_MEMORY}MB (threshold: ${MEMORY_THRESHOLD}MB)" echo "Apache processes:" ps aux | grep "$APACHE_PROC" | grep -v grep # Add your alerting logic here (email, webhook, etc.) else echo "Apache memory usage: ${TOTAL_MEMORY}MB (OK)" fi
sudo chmod +x /usr/local/bin/apache-memory-monitor.sh

Schedule regular memory checks

Use cron to run memory checks every 5 minutes and log the results.

sudo crontab -e
# Apache memory monitoring every 5 minutes
/5    * /usr/local/bin/apache-memory-monitor.sh >> /var/log/apache-memory.log 2>&1

Set up log rotation for monitoring logs

Prevent monitoring logs from consuming excessive disk space.

/var/log/apache-memory.log {
    daily
    rotate 7
    compress
    delaycompress
    missingok
    notifempty
}

Apply kernel-level memory optimizations

Configure system memory settings

Optimize kernel parameters to better handle web server memory patterns.

# Reduce swap usage (good for web servers with enough RAM)
vm.swappiness=10

Increase file handle limits for high-traffic servers

fs.file-max=65536

Optimize TCP memory for web connections

net.ipv4.tcp_mem=65536 131072 262144 net.core.rmem_max=16777216 net.core.wmem_max=16777216
sudo sysctl -p /etc/sysctl.d/99-apache-memory.conf

For more advanced kernel tuning, see our comprehensive sysctl optimization guide.

Increase system limits for Apache

Configure systemd to allow Apache to use more file descriptors and memory.

[Service]
LimitNOFILE=65536
LimitNPROC=4096
sudo mkdir -p /etc/systemd/system/apache2.service.d
sudo systemctl daemon-reload
sudo systemctl restart apache2
[Service]
LimitNOFILE=65536
LimitNPROC=4096
sudo mkdir -p /etc/systemd/system/httpd.service.d
sudo systemctl daemon-reload
sudo systemctl restart httpd

Verify your setup

Test Apache configuration

Ensure all configuration changes are syntactically correct before restarting.

sudo apache2ctl configtest
sudo systemctl restart apache2
sudo systemctl status apache2
sudo httpd -t
sudo systemctl restart httpd
sudo systemctl status httpd

Monitor memory usage after optimization

Compare memory usage before and after your changes to measure improvement.

# Check current memory usage
ps aux | grep -E "apache2|httpd" | grep -v grep | awk '{sum+=$6} END {print "Total Apache memory: " sum/1024 " MB"}'

Test server performance under load

Use Apache's built-in benchmarking tool to verify performance improvements.

ab -n 1000 -c 10 http://localhost/

Monitor memory during the test:

watch 'ps aux | grep -E "apache2|httpd" | grep -v grep'

Common issues

SymptomCauseFix
Apache won't start after MPM changePHP module incompatible with Event MPMInstall libapache2-mod-php-fpm and configure PHP-FPM instead
Still high memory usageMemory leaks in PHP applicationsEnable PHP-FPM with pm.max_requests = 500 to restart workers periodically
Connection timeouts increasedKeepAliveTimeout too lowIncrease to 5 seconds for slower clients
Configuration test failsMissing required modulesRe-enable essential modules like mod_mime and mod_dir
High swap usageMaxRequestWorkers set too highReduce to fit available RAM: (RAM - 1GB) / 25MB
502 errors with PHP-FPMFPM socket permissionsSet listen.owner = www-data in FPM pool config

Next steps

Running this in production?

Want this handled for you? Setting up Apache optimization once is straightforward. Keeping it tuned, monitored, and performing well under varying loads is the harder part. See how we run infrastructure like this for European SaaS and e-commerce teams.

Automated install script

Run this to automate the entire setup

Need help?

Don't want to manage this yourself?

We handle managed cloud infrastructure for businesses that depend on uptime. From initial setup to ongoing operations.