When tuning Apache's MaxClients parameter, accurately measuring memory consumption per process is crucial. The pmap output you're seeing represents the virtual memory size (VSZ), which includes shared libraries and may overestimate actual RAM usage.
# Sample command to get process memory info
pmap pgrep apache2 | grep total
# Output example:
# total 47768K
# total 48048K
# total 48048K
For server tuning, we need resident set size (RSS) - the actual physical memory being used. Here are better approaches:
# Method 1: Using ps for RSS measurement
ps -ylC apache2 | awk '{print $8}'
# RSS column shows KB of physical memory
# Method 2: Detailed memory breakdown
for pid in $(pgrep apache2); do
echo "PID $pid: $(pmap -x $pid | tail -1)";
done
To determine MaxClients, calculate average RSS across multiple processes during typical load:
# Calculate average RSS in MB
ps -eo rss,comm | grep apache2 | \
awk '{sum+=$1} END {print "Average=",sum/NR/1024,"MB"}'
Here's a complete script to analyze Apache memory usage and suggest MaxClients:
#!/bin/bash
# Apache memory analyzer script
# Get current memory usage stats
TOTAL_MEM=$(free -m | awk '/Mem:/ {print $2}')
AVAIL_MEM=$(free -m | awk '/Mem:/ {print $7}')
APACHE_PROCS=$(pgrep apache2 | wc -l)
echo "System Memory: ${TOTAL_MEM}MB total, ${AVAIL_MEM}MB available"
echo "Running Apache processes: ${APACHE_PROCS}"
# Calculate average per-process memory
AVG_MEM=$(ps -eo rss,comm | awk '/apache2/ {sum+=$1} END {printf "%.1f", sum/NR/1024}')
echo "Average Apache process memory: ${AVG_MEM}MB"
# Calculate suggested MaxClients (80% of available memory)
SUGGESTED_MAX=$(( (AVAIL_MEM * 80 / 100) / ${AVG_MEM%.*} ))
echo "Suggested MaxClients: ${SUGGESTED_MAX}"
- Measure during peak traffic for accurate numbers
- Account for other services running on the server
- Leave 20-30% memory free for system processes
- Monitor memory usage after configuration changes
When running Apache on Ubuntu, I recently used pmap $(pgrep apache2) | grep total
to analyze memory consumption and got output like:
total 47768K total 48048K total 48048K total 48048K total 48048K total 48048K
While these numbers give a rough estimate (≈48MB per process), we need more precise methods to properly configure MaxClients.
For accurate measurements, consider these approaches:
# Method 1: Detailed RSS measurement ps -o pid,user,rss,command -C apache2 | awk '{print $1,$3/1024"MB",$4,$5,$6,$7}' # Method 2: Using smem for shared memory calculation sudo smem -P apache2 -c "pid rss uss pss"
Here's a complete workflow to determine optimal MaxClients:
#!/bin/bash # Calculate average Apache process size PROC_SIZE=$(ps -ylC apache2 --sort:rss | awk '{sum+=$8; count++} END {print sum/count/1024}') FREE_MEM=$(free -m | awk '/Mem:/ {print $4}') MAX_CLIENTS=$(echo "$FREE_MEM*0.8/$PROC_SIZE" | bc) echo "Recommended MaxClients: $MAX_CLIENTS (based on ${PROC_SIZE}MB per process)"
For production servers, consider these additional factors:
- Account for 20% memory headroom for OS operations
- Monitor memory usage patterns during peak loads
- Consider using mod_wsgi or PHP-FPM for better memory isolation
A typical LAMP stack configuration might look like:
StartServers 5 MinSpareServers 5 MaxSpareServers 10 MaxRequestWorkers 150 MaxConnectionsPerChild 10000
Remember to adjust these values after thorough memory profiling.