Boost Apache performance through worker MPM optimization, compression modules, and intelligent caching strategies. Achieve 3-5x performance improvements for high-traffic production workloads.
Prerequisites
- Root or sudo access
- 4GB+ RAM recommended for high-performance settings
- Basic knowledge of Apache configuration
What this solves
Apache HTTP server performance can bottleneck under high traffic loads due to inefficient worker configurations, missing compression, and lack of caching. This tutorial optimizes Apache through worker MPM tuning for concurrent connections, enables mod_deflate and Brotli compression to reduce bandwidth usage, and implements browser and proxy caching with mod_cache. These optimizations typically improve response times by 60-80% and increase concurrent user capacity by 3-5x.
Step-by-step configuration
Update system packages and install Apache
Start with a fresh Apache installation and enable essential performance modules.
sudo apt update && sudo apt upgrade -y
sudo apt install -y apache2 apache2-utils brotli
sudo systemctl enable apache2
sudo dnf update -y
sudo dnf install -y httpd httpd-tools brotli
sudo systemctl enable httpd
Enable performance and compression modules
Enable Apache modules required for performance optimization including worker MPM, compression, caching, and monitoring.
sudo a2dismod mpm_prefork
sudo a2enmod mpm_worker
sudo a2enmod deflate
sudo a2enmod expires
sudo a2enmod headers
sudo a2enmod cache
sudo a2enmod cache_disk
sudo a2enmod status
sudo a2enmod info
sudo a2enmod rewrite
# Modules are compiled in by default on RHEL-based systems
# Create module loading configuration
sudo tee /etc/httpd/conf.modules.d/00-performance.conf > /dev/null << 'EOF'
LoadModule mpm_worker_module modules/mod_mpm_worker.so
LoadModule deflate_module modules/mod_deflate.so
LoadModule expires_module modules/mod_expires.so
LoadModule headers_module modules/mod_headers.so
LoadModule cache_module modules/mod_cache.so
LoadModule cache_disk_module modules/mod_cache_disk.so
LoadModule status_module modules/mod_status.so
LoadModule info_module modules/mod_info.so
LoadModule rewrite_module modules/mod_rewrite.so
EOF
Configure worker MPM for high concurrency
Optimize worker process and thread settings based on your server resources. These settings handle 4GB+ RAM servers with high concurrent loads.
Configure compression with mod_deflate
Enable gzip compression for text-based content to reduce bandwidth usage by 60-80%. This configuration targets common web content types.
Configure Brotli compression
Enable Brotli compression for better compression ratios than gzip, especially for text content. Brotli provides 15-25% better compression.
sudo apt install -y libapache2-mod-brotli
sudo a2enmod brotli
# Install mod_brotli from EPEL
sudo dnf install -y epel-release
sudo dnf install -y httpd-mod-brotli
Configure disk-based caching with mod_cache
Enable intelligent caching to serve frequently requested content from disk cache, reducing server load and improving response times.
# Create cache directory with proper permissions
sudo mkdir -p /var/cache/apache2/mod_cache_disk
sudo chown www-data:www-data /var/cache/apache2/mod_cache_disk
sudo chmod 755 /var/cache/apache2/mod_cache_disk
sudo mkdir -p /var/cache/httpd/mod_cache_disk
sudo chown apache:apache /var/cache/httpd/mod_cache_disk
sudo chmod 755 /var/cache/httpd/mod_cache_disk
Configure browser caching with expires headers
Set appropriate expiration headers to enable browser caching and reduce repeat requests for static assets.
Configure performance monitoring with mod_status
Enable server status and info pages for performance monitoring. Restrict access to localhost for security.
Apply security hardening for performance modules
Secure the performance configuration by hiding server information and preventing information disclosure.
# Hide Apache version and OS information
ServerTokens Prod
ServerSignature Off
# Prevent access to .htaccess files
# Prevent access to cache directories
# Security headers for performance-related content
# Limit request size to prevent DoS
LimitRequestBody 10485760
LimitRequestFields 100
LimitRequestFieldSize 1024
LimitRequestLine 4094
sudo a2enconf security-performance
# Hide Apache version and OS information
ServerTokens Prod
ServerSignature Off
# Prevent access to .htaccess files
# Prevent access to cache directories
# Security headers for performance-related content
# Limit request size to prevent DoS
LimitRequestBody 10485760
LimitRequestFields 100
LimitRequestFieldSize 1024
LimitRequestLine 4094
Configure firewall access
Ensure Apache can accept HTTP and HTTPS connections through the system firewall.
sudo ufw allow 'Apache Full'
sudo ufw reload
sudo ufw status
sudo firewall-cmd --permanent --add-service=http
sudo firewall-cmd --permanent --add-service=https
sudo firewall-cmd --reload
sudo firewall-cmd --list-services
Start and enable Apache service
Start Apache with the new performance configuration and enable automatic startup.
Automated install script
Run this to automate the entire setup
#!/usr/bin/env bash
set -euo pipefail
# Apache HTTP Server Performance Optimization Script
# Optimizes Apache with caching, compression, and worker tuning
# Colors
readonly RED='\033[0;31m'
readonly GREEN='\033[0;32m'
readonly YELLOW='\033[1;33m'
readonly NC='\033[0m'
# Configuration
DOMAIN="${1:-localhost}"
WORKER_THREADS="${2:-25}"
MAX_CONNECTIONS="${3:-400}"
usage() {
echo "Usage: $0 [domain] [worker_threads] [max_connections]"
echo " domain: Domain name (default: localhost)"
echo " worker_threads: Threads per child process (default: 25)"
echo " max_connections: Maximum connections (default: 400)"
exit 1
}
log() { echo -e "${GREEN}[INFO]${NC} $*"; }
warn() { echo -e "${YELLOW}[WARN]${NC} $*"; }
error() { echo -e "${RED}[ERROR]${NC} $*" >&2; exit 1; }
# Check root privileges
[[ $EUID -eq 0 ]] || error "This script must be run as root"
# Detect distribution
if [[ ! -f /etc/os-release ]]; then
error "Cannot detect distribution - /etc/os-release not found"
fi
. /etc/os-release
case "$ID" in
ubuntu|debian)
PKG_MGR="apt"
PKG_INSTALL="apt install -y"
PKG_UPDATE="apt update && apt upgrade -y"
APACHE_SERVICE="apache2"
APACHE_CONF_DIR="/etc/apache2"
APACHE_SITES_DIR="/etc/apache2/sites-available"
APACHE_MODS_DIR="/etc/apache2/mods-available"
APACHE_LOG_DIR="/var/log/apache2"
APACHE_CACHE_DIR="/var/cache/apache2/mod_cache_disk"
;;
almalinux|rocky|centos|rhel|ol|fedora)
PKG_MGR="dnf"
PKG_INSTALL="dnf install -y"
PKG_UPDATE="dnf update -y"
APACHE_SERVICE="httpd"
APACHE_CONF_DIR="/etc/httpd"
APACHE_SITES_DIR="/etc/httpd/conf.d"
APACHE_MODS_DIR="/etc/httpd/conf.modules.d"
APACHE_LOG_DIR="/var/log/httpd"
APACHE_CACHE_DIR="/var/cache/httpd/mod_cache_disk"
;;
amzn)
PKG_MGR="yum"
PKG_INSTALL="yum install -y"
PKG_UPDATE="yum update -y"
APACHE_SERVICE="httpd"
APACHE_CONF_DIR="/etc/httpd"
APACHE_SITES_DIR="/etc/httpd/conf.d"
APACHE_MODS_DIR="/etc/httpd/conf.modules.d"
APACHE_LOG_DIR="/var/log/httpd"
APACHE_CACHE_DIR="/var/cache/httpd/mod_cache_disk"
;;
*)
error "Unsupported distribution: $ID"
;;
esac
# Cleanup on error
cleanup() {
warn "Script failed, performing cleanup..."
systemctl stop $APACHE_SERVICE 2>/dev/null || true
}
trap cleanup ERR
echo "[1/8] Updating system packages and installing Apache..."
$PKG_UPDATE
if [[ "$ID" =~ ^(ubuntu|debian)$ ]]; then
$PKG_INSTALL apache2 apache2-utils brotli libapache2-mod-brotli
else
$PKG_INSTALL httpd httpd-tools brotli
# Try to install mod_brotli from EPEL
$PKG_INSTALL epel-release 2>/dev/null || true
$PKG_INSTALL httpd-mod-brotli 2>/dev/null || warn "mod_brotli not available from repositories"
fi
systemctl enable $APACHE_SERVICE
echo "[2/8] Enabling performance modules..."
if [[ "$ID" =~ ^(ubuntu|debian)$ ]]; then
a2dismod mpm_prefork 2>/dev/null || true
a2enmod mpm_worker deflate expires headers cache cache_disk status info rewrite
[[ -f /etc/apache2/mods-available/brotli.load ]] && a2enmod brotli || warn "Brotli module not available"
else
# Create module configuration for RHEL-based systems
cat > "$APACHE_MODS_DIR/00-performance.conf" << 'EOF'
LoadModule deflate_module modules/mod_deflate.so
LoadModule expires_module modules/mod_expires.so
LoadModule headers_module modules/mod_headers.so
LoadModule cache_module modules/mod_cache.so
LoadModule cache_disk_module modules/mod_cache_disk.so
LoadModule status_module modules/mod_status.so
LoadModule info_module modules/mod_info.so
LoadModule rewrite_module modules/mod_rewrite.so
EOF
[[ -f /etc/httpd/modules/mod_brotli.so ]] && echo "LoadModule brotli_module modules/mod_brotli.so" >> "$APACHE_MODS_DIR/00-performance.conf"
fi
echo "[3/8] Configuring worker MPM..."
cat > "$APACHE_CONF_DIR/conf$([ "$ID" =~ ^(ubuntu|debian)$ ] && echo '-available' || echo '.d')/worker-mpm.conf" << EOF
<IfModule mpm_worker_module>
ServerLimit 16
MaxRequestWorkers $MAX_CONNECTIONS
ThreadsPerChild $WORKER_THREADS
ThreadLimit 64
StartServers 3
MinSpareThreads 75
MaxSpareThreads 250
MaxConnectionsPerChild 10000
</IfModule>
EOF
[[ "$ID" =~ ^(ubuntu|debian)$ ]] && a2enconf worker-mpm
echo "[4/8] Setting up compression with mod_deflate..."
cat > "$APACHE_SITES_DIR/compression.conf" << 'EOF'
<IfModule mod_deflate.c>
# Enable deflate compression
SetOutputFilter DEFLATE
# Compress these file types
AddOutputFilterByType DEFLATE text/html text/plain text/xml text/css text/javascript
AddOutputFilterByType DEFLATE application/javascript application/json application/xml
AddOutputFilterByType DEFLATE application/rss+xml application/atom+xml image/svg+xml
# Set compression level (1-9, 9 is highest)
DeflateCompressionLevel 6
# Don't compress already compressed files
SetEnvIfNoCase Request_URI \.(?:gif|jpe?g|png|zip|gz|rar|bz2|7z|mp[34]|avi|mov)$ no-gzip
# Add Vary header for caching proxies
Header append Vary Accept-Encoding env=!dont-vary
</IfModule>
EOF
echo "[5/8] Configuring Brotli compression..."
cat > "$APACHE_SITES_DIR/brotli.conf" << 'EOF'
<IfModule mod_brotli.c>
# Enable Brotli compression
BrotliCompressionQuality 6
BrotliCompressionWindow 22
# Compress these MIME types with Brotli
AddOutputFilterByType BROTLI_COMPRESS text/html text/plain text/xml text/css
AddOutputFilterByType BROTLI_COMPRESS text/javascript application/javascript
AddOutputFilterByType BROTLI_COMPRESS application/json application/xml
AddOutputFilterByType BROTLI_COMPRESS application/rss+xml application/atom+xml
AddOutputFilterByType BROTLI_COMPRESS image/svg+xml
</IfModule>
EOF
echo "[6/8] Setting up caching configuration..."
# Create cache directory
mkdir -p "$APACHE_CACHE_DIR"
chown -R $([ "$ID" =~ ^(ubuntu|debian)$ ] && echo "www-data:www-data" || echo "apache:apache") "$APACHE_CACHE_DIR"
chmod 755 "$APACHE_CACHE_DIR"
cat > "$APACHE_SITES_DIR/caching.conf" << EOF
<IfModule mod_cache.c>
<IfModule mod_cache_disk.c>
CacheRoot $APACHE_CACHE_DIR
CacheEnable disk /
CacheDirLevels 2
CacheDirLength 1
CacheMaxFileSize 10000000
CacheDefaultExpire 3600
CacheMaxExpire 86400
</IfModule>
</IfModule>
<IfModule mod_expires.c>
ExpiresActive On
ExpiresByType text/css "access plus 1 month"
ExpiresByType application/javascript "access plus 1 month"
ExpiresByType image/png "access plus 1 year"
ExpiresByType image/jpg "access plus 1 year"
ExpiresByType image/jpeg "access plus 1 year"
ExpiresByType image/gif "access plus 1 year"
ExpiresByType image/svg+xml "access plus 1 month"
ExpiresByType text/html "access plus 1 hour"
</IfModule>
<IfModule mod_headers.c>
Header set Cache-Control "public, max-age=2592000" "expr=%{CONTENT_TYPE} =~ m#^image/#"
Header set Cache-Control "public, max-age=604800" "expr=%{CONTENT_TYPE} =~ m#^text/(css|javascript)#"
</IfModule>
EOF
echo "[7/8] Configuring server status monitoring..."
cat > "$APACHE_SITES_DIR/status.conf" << 'EOF'
<Location "/server-status">
SetHandler server-status
Require local
</Location>
<Location "/server-info">
SetHandler server-info
Require local
</Location>
EOF
# Enable configurations on Debian-based systems
if [[ "$ID" =~ ^(ubuntu|debian)$ ]]; then
a2enconf compression brotli caching status 2>/dev/null || true
fi
echo "[8/8] Starting and verifying Apache configuration..."
# Test configuration
if ! $APACHE_SERVICE -t 2>/dev/null; then
error "Apache configuration test failed"
fi
# Start Apache
systemctl start $APACHE_SERVICE
systemctl reload $APACHE_SERVICE
# Configure firewall
if command -v ufw &> /dev/null && ufw status | grep -q "Status: active"; then
ufw allow 'Apache Full' || ufw allow 80/tcp && ufw allow 443/tcp
elif command -v firewall-cmd &> /dev/null && systemctl is-active --quiet firewalld; then
firewall-cmd --permanent --add-service=http
firewall-cmd --permanent --add-service=https
firewall-cmd --reload
fi
# Verification
log "Verifying Apache optimization..."
if systemctl is-active --quiet $APACHE_SERVICE; then
log "✓ Apache is running"
else
error "Apache failed to start"
fi
if $APACHE_SERVICE -M | grep -q "deflate_module"; then
log "✓ Deflate compression enabled"
fi
if $APACHE_SERVICE -M | grep -q "brotli_module"; then
log "✓ Brotli compression enabled"
else
warn "Brotli compression not available"
fi
if $APACHE_SERVICE -M | grep -q "cache_module"; then
log "✓ Caching modules enabled"
fi
log "Apache optimization completed successfully!"
log "Server status available at: http://$DOMAIN/server-status"
log "Configuration test: systemctl status $APACHE_SERVICE"
log "Cache directory: $APACHE_CACHE_DIR"
Review the script before running. Execute with: bash install.sh