The provided LAMP stack configuration shows aggressive prefork settings combined with relatively low PHP memory limits. Let's break down the key parameters:
# Apache Prefork MPM settings StartServers 64 MinSpareServers 64 MaxSpareServers 128 ServerLimit 256 MaxClients 256 MaxRequestsPerChild 4096 # PHP settings max_execution_time = 30 max_input_time = 30 memory_limit = 80M
From the top
screenshot analysis (though not visible here), we can infer several critical memory consumption patterns:
- Numerous Apache processes consuming significant RAM
- PHP processes hitting the 80MB limit frequently
- System cache/buffers consuming available memory
The current prefork settings may be too aggressive for typical web servers. Here's a more balanced configuration:
StartServers 8 MinSpareServers 5 MaxSpareServers 10 ServerLimit 150 MaxClients 150 MaxRequestsPerChild 1000
Key adjustments:
- Reduced initial server count to decrease cold-start memory pressure
- Tighter spare server range to maintain responsiveness without waste
- Lowered MaxClients to prevent OOM situations
- More frequent process recycling to prevent memory leaks
Consider these php.ini adjustments:
memory_limit = 128M # Increased from 80MB max_execution_time = 60 # Allows more complex operations realpath_cache_size = 256k # Reduces filesystem ops opcache.enable=1 # Enable opcode caching opcache.memory_consumption=128 # MB allocated for opcache
Combine this with application-level improvements:
// Example memory-saving technique in PHP function process_large_data() { // Process in chunks $chunkSize = 1000; $total = 100000; for ($i = 0; $i < $total; $i += $chunkSize) { $data = get_data_chunk($i, $chunkSize); process_chunk($data); unset($data); // Explicit memory cleanup gc_collect_cycles(); // Force garbage collection } }
Implement these Linux kernel parameters in /etc/sysctl.conf:
vm.swappiness = 10 # Reduce tendency to swap vm.vfs_cache_pressure = 50 # Balance between cache and process memory vm.dirty_ratio = 10 # Aggressive writeback of dirty pages vm.dirty_background_ratio = 5 # Background writeback threshold
Apply changes with:
sudo sysctl -p
For high-traffic sites, evaluate these alternatives:
- Event MPM (replaces prefork for better concurrency)
- PHP-FPM with nginx for more efficient process management
- Reverse proxy cache (Varnish or Nginx cache)
Example Event MPM configuration:
StartServers 2 MinSpareThreads 25 MaxSpareThreads 75 ThreadLimit 64 ThreadsPerChild 25 MaxRequestWorkers 150 MaxConnectionsPerChild 1000
Implement these monitoring solutions:
# Sample cron job for memory monitoring */5 * * * * /usr/bin/free -m | awk '/^Mem/ {if ($3/$2 > 0.8) system("/usr/sbin/service apache2 restart")}' # Install and configure prometheus node exporter apt install prometheus-node-exporter
Example Grafana dashboard metrics to track:
- Apache scoreboard states (waiting/reading/sending)
- PHP process memory usage distribution
- Swap usage trends over time
- System cache/buffer ratios
When your LAMP servers start choking on swap space, it's often a configuration mismatch between Apache's process management and PHP's resource limits. The top
screenshot reveals classic symptoms: too many Apache processes competing for limited memory resources.
The current prefork configuration creates unnecessary memory pressure:
<IfModule prefork.c> StartServers 64 # Too aggressive for most workloads MinSpareServers 64 # Keeps too many idle processes MaxSpareServers 128 # Wastes memory on standby ServerLimit 256 # Dangerously high ceiling MaxClients 256 # Recipe for OOM disasters MaxRequestsPerChild 4096 </IfModule>
Try this optimized setup for a 4GB RAM server:
<IfModule prefork.c> StartServers 8 MinSpareServers 5 MaxSpareServers 10 ServerLimit 50 MaxClients 50 MaxRequestsPerChild 1000 # Helps prevent memory leaks </IfModule>
The 80MB memory_limit
might be insufficient for modern PHP applications. Consider this graduated approach:
; php.ini adjustments memory_limit = 128M # Baseline for most CMS platforms max_execution_time = 45 # Slightly more breathing room realpath_cache_size = 256k # Reduces filesystem overhead opcache.enable=1 # Critical for performance
Install this quick diagnostic script at /var/www/html/memcheck.php
:
<?php header('Content-Type: text/plain'); echo "Memory usage: " . memory_get_usage()/1024 . "KB\n"; echo "Peak usage: " . memory_get_peak_usage()/1024 . "KB\n"; echo "PHP limit: " . ini_get('memory_limit') . "\n"; $apache = shell_exec('ps -ylC apache2 --sort:rss | awk \'{sum+=$8} END {print sum/1024}\''); echo "Total Apache RSS: " . $apache . "MB\n"; ?>
For high-traffic sites, consider migrating to mpm_event with PHP-FPM:
# Install required modules sudo apt install apache2 apache2-bin apache2-data apache2-utils libapache2-mod-fcgid libapache2-mod-php # Sample FPM pool configuration [www] user = www-data group = www-data listen = /run/php/php7.4-fpm.sock pm = dynamic pm.max_children = 30 pm.start_servers = 5 pm.min_spare_servers = 3 pm.max_spare_servers = 10
Modify swappiness to prioritize RAM usage:
# Check current value cat /proc/sys/vm/swappiness # Temporary change sudo sysctl vm.swappiness=10 # Permanent setting echo "vm.swappiness=10" >> /etc/sysctl.conf