Optimize Apache HTTP server performance with caching, compression and worker tuning

Intermediate 35 min Apr 03, 2026 51 views
Ubuntu 24.04 Ubuntu 22.04 Debian 12 AlmaLinux 9 Rocky Linux 9 Fedora 41

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.


    StartServers            4
    MinSpareThreads         50
    MaxSpareThreads         200
    ThreadLimit             64
    ThreadsPerChild         32
    MaxRequestWorkers       1024
    MaxConnectionsPerChild  10000
    ServerLimit             32

    StartServers            4
    MinSpareThreads         50
    MaxSpareThreads         200
    ThreadLimit             64
    ThreadsPerChild         32
    MaxRequestWorkers       1024
    MaxConnectionsPerChild  10000
    ServerLimit             32

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.


    # Compress these file types
    AddOutputFilterByType DEFLATE text/html
    AddOutputFilterByType DEFLATE text/plain
    AddOutputFilterByType DEFLATE text/xml
    AddOutputFilterByType DEFLATE text/css
    AddOutputFilterByType DEFLATE text/javascript
    AddOutputFilterByType DEFLATE application/javascript
    AddOutputFilterByType DEFLATE application/json
    AddOutputFilterByType DEFLATE application/xml
    AddOutputFilterByType DEFLATE application/rss+xml
    AddOutputFilterByType DEFLATE application/atom+xml
    AddOutputFilterByType DEFLATE image/svg+xml
    
    # Set compression level (1-9, 9 is highest)
    DeflateCompressionLevel 6
    
    # Don't compress images, videos, or already compressed files
    SetEnvIfNoCase Request_URI \.(?:gif|jpe?g|png|zip|gz|rar|bz2|7z|mp3|mp4|avi|mov)$ no-gzip
    
    # Add Vary header for caching proxies
    Header append Vary Accept-Encoding env=!dont-vary
    
    # Log compression ratio for monitoring
    LogFormat '%h %l %u %t "%r" %>s %O "%{Referer}i" "%{User-Agent}i" %{ratio}n%%' deflate

    # Compress these file types
    AddOutputFilterByType DEFLATE text/html
    AddOutputFilterByType DEFLATE text/plain
    AddOutputFilterByType DEFLATE text/xml
    AddOutputFilterByType DEFLATE text/css
    AddOutputFilterByType DEFLATE text/javascript
    AddOutputFilterByType DEFLATE application/javascript
    AddOutputFilterByType DEFLATE application/json
    AddOutputFilterByType DEFLATE application/xml
    AddOutputFilterByType DEFLATE application/rss+xml
    AddOutputFilterByType DEFLATE application/atom+xml
    AddOutputFilterByType DEFLATE image/svg+xml
    
    # Set compression level (1-9, 9 is highest)
    DeflateCompressionLevel 6
    
    # Don't compress images, videos, or already compressed files
    SetEnvIfNoCase Request_URI \.(?:gif|jpe?g|png|zip|gz|rar|bz2|7z|mp3|mp4|avi|mov)$ no-gzip
    
    # Add Vary header for caching proxies
    Header append Vary Accept-Encoding env=!dont-vary
    
    # Log compression ratio for monitoring
    LogFormat '%h %l %u %t "%r" %>s %O "%{Referer}i" "%{User-Agent}i" %{ratio}n%%' deflate

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

    # Enable Brotli compression
    BrotliCompressionQuality 6
    BrotliCompressionWindow 22
    
    # Compress these MIME types with Brotli
    BrotliFilterNote Input instream
    BrotliFilterNote Output outstream
    BrotliFilterNote Ratio ratio
    
    AddOutputFilterByType BROTLI_COMPRESS text/html
    AddOutputFilterByType BROTLI_COMPRESS text/plain
    AddOutputFilterByType BROTLI_COMPRESS text/xml
    AddOutputFilterByType BROTLI_COMPRESS text/css
    AddOutputFilterByType BROTLI_COMPRESS text/javascript
    AddOutputFilterByType BROTLI_COMPRESS application/javascript
    AddOutputFilterByType BROTLI_COMPRESS application/json
    AddOutputFilterByType BROTLI_COMPRESS application/xml
    AddOutputFilterByType BROTLI_COMPRESS application/rss+xml
    AddOutputFilterByType BROTLI_COMPRESS application/atom+xml
    AddOutputFilterByType BROTLI_COMPRESS image/svg+xml
    
    # Fallback to deflate for clients that don't support Brotli
    
        SetOutputFilter BROTLI_COMPRESS;DEFLATE
    

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

    
        CacheRoot /var/cache/apache2/mod_cache_disk
        CacheDirLevels 2
        CacheDirLength 1
        CacheEnable disk /
        
        # Cache configuration
        CacheMaxFileSize 10000000
        CacheMinFileSize 1
        CacheDefaultExpire 3600
        CacheMaxExpire 86400
        
        # Don't cache these paths
        CacheDisable /admin
        CacheDisable /api
        CacheDisable /login
        CacheDisable /wp-admin
        
        # Cache based on query strings
        CacheIgnoreQueryString Off
        
        # Add cache status headers
        CacheHeader on
    
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

    
        CacheRoot /var/cache/httpd/mod_cache_disk
        CacheDirLevels 2
        CacheDirLength 1
        CacheEnable disk /
        
        # Cache configuration
        CacheMaxFileSize 10000000
        CacheMinFileSize 1
        CacheDefaultExpire 3600
        CacheMaxExpire 86400
        
        # Don't cache these paths
        CacheDisable /admin
        CacheDisable /api
        CacheDisable /login
        CacheDisable /wp-admin
        
        # Cache based on query strings
        CacheIgnoreQueryString Off
        
        # Add cache status headers
        CacheHeader on
    

Configure browser caching with expires headers

Set appropriate expiration headers to enable browser caching and reduce repeat requests for static assets.


    ExpiresActive On
    
    # Default expiration: 1 hour
    ExpiresDefault "access plus 1 hour"
    
    # HTML documents: 10 minutes
    ExpiresByType text/html "access plus 10 minutes"
    
    # CSS and JavaScript: 1 week
    ExpiresByType text/css "access plus 1 week"
    ExpiresByType application/javascript "access plus 1 week"
    ExpiresByType text/javascript "access plus 1 week"
    
    # Images: 1 month
    ExpiresByType image/png "access plus 1 month"
    ExpiresByType image/jpg "access plus 1 month"
    ExpiresByType image/jpeg "access plus 1 month"
    ExpiresByType image/gif "access plus 1 month"
    ExpiresByType image/svg+xml "access plus 1 month"
    ExpiresByType image/webp "access plus 1 month"
    
    # Fonts: 3 months
    ExpiresByType font/ttf "access plus 3 months"
    ExpiresByType font/woff "access plus 3 months"
    ExpiresByType font/woff2 "access plus 3 months"
    ExpiresByType application/font-woff "access plus 3 months"
    
    # Documents and media: 1 week
    ExpiresByType application/pdf "access plus 1 week"
    ExpiresByType video/mp4 "access plus 1 week"
    ExpiresByType audio/mpeg "access plus 1 week"
    
    # Add cache-control headers
    
        Header append Cache-Control "public"
    

    ExpiresActive On
    
    # Default expiration: 1 hour
    ExpiresDefault "access plus 1 hour"
    
    # HTML documents: 10 minutes
    ExpiresByType text/html "access plus 10 minutes"
    
    # CSS and JavaScript: 1 week
    ExpiresByType text/css "access plus 1 week"
    ExpiresByType application/javascript "access plus 1 week"
    ExpiresByType text/javascript "access plus 1 week"
    
    # Images: 1 month
    ExpiresByType image/png "access plus 1 month"
    ExpiresByType image/jpg "access plus 1 month"
    ExpiresByType image/jpeg "access plus 1 month"
    ExpiresByType image/gif "access plus 1 month"
    ExpiresByType image/svg+xml "access plus 1 month"
    ExpiresByType image/webp "access plus 1 month"
    
    # Fonts: 3 months
    ExpiresByType font/ttf "access plus 3 months"
    ExpiresByType font/woff "access plus 3 months"
    ExpiresByType font/woff2 "access plus 3 months"
    ExpiresByType application/font-woff "access plus 3 months"
    
    # Documents and media: 1 week
    ExpiresByType application/pdf "access plus 1 week"
    ExpiresByType video/mp4 "access plus 1 week"
    ExpiresByType audio/mpeg "access plus 1 week"
    
    # Add cache-control headers
    
        Header append Cache-Control "public"
    

Configure performance monitoring with mod_status

Enable server status and info pages for performance monitoring. Restrict access to localhost for security.


    
        SetHandler server-status
        Require local
        Require ip 127.0.0.1
        Require ip ::1
    
    
    
        SetHandler server-info
        Require local
        Require ip 127.0.0.1
        Require ip ::1
    
    
    # Enable extended status for detailed metrics
    ExtendedStatus On

    
        SetHandler server-status
        Require local
        Require ip 127.0.0.1
        Require ip ::1
    
    
    
        SetHandler server-info
        Require local
        Require ip 127.0.0.1
        Require ip ::1
    
    
    # Enable extended status for detailed metrics
    ExtendedStatus On

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

Require all denied

Prevent access to cache directories

Require all denied

Security headers for performance-related content

# Prevent MIME type sniffing Header always set X-Content-Type-Options nosniff # Enable XSS protection Header always set X-XSS-Protection "1; mode=block" # Prevent clickjacking Header always set X-Frame-Options SAMEORIGIN # Remove server header information Header unset Server Header unset X-Powered-By

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

Require all denied

Prevent access to cache directories

Require all denied

Security headers for performance-related content

# Prevent MIME type sniffing Header always set X-Content-Type-Options nosniff # Enable XSS protection Header always set X-XSS-Protection "1; mode=block" # Prevent clickjacking Header always set X-Frame-Options SAMEORIGIN # Remove server header information Header unset Server Header unset X-Powered-By

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.

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

Performance benchmarking and monitoring

Install Apache Bench for load testing

Install ab (Apache Bench) tool for performance testing and establish baseline metrics.

# apache2-utils already installed above
ab -V
# httpd-tools already installed above
ab -V

Create test content for benchmarking

Create sample content to test compression and caching performance accurately.

sudo mkdir -p /var/www/html/test
sudo tee /var/www/html/test/large.html > /dev/null << 'EOF'



    Performance Test Page
    


    

Apache Performance Test Content

EOF

Add repetitive content for compression testing

for i in {1..1000}; do echo "

This is test paragraph number $i with repeated content for compression testing. Lorem ipsum dolor sit amet, consectetur adipiscing elit.

" | sudo tee -a /var/www/html/test/large.html > /dev/null done echo "
" | sudo tee -a /var/www/html/test/large.html > /dev/null sudo chown -R www-data:www-data /var/www/html/test sudo chmod -R 644 /var/www/html/test/*
sudo mkdir -p /var/www/html/test
sudo tee /var/www/html/test/large.html > /dev/null << 'EOF'



    Performance Test Page
    


    

Apache Performance Test Content

EOF

Add repetitive content for compression testing

for i in {1..1000}; do echo "

This is test paragraph number $i with repeated content for compression testing. Lorem ipsum dolor sit amet, consectetur adipiscing elit.

" | sudo tee -a /var/www/html/test/large.html > /dev/null done echo "
" | sudo tee -a /var/www/html/test/large.html > /dev/null sudo chown -R apache:apache /var/www/html/test sudo chmod -R 644 /var/www/html/test/*

Run performance benchmarks

Execute comprehensive load tests to measure the performance improvements from your optimizations.

# Test concurrent connections (100 concurrent, 1000 total requests)
ab -n 1000 -c 100 http://localhost/test/large.html

Test with different concurrency levels

ab -n 2000 -c 200 http://localhost/test/large.html

Test compression effectiveness

curl -H "Accept-Encoding: gzip" -s http://localhost/test/large.html | wc -c curl -s http://localhost/test/large.html | wc -c

Test Brotli compression

curl -H "Accept-Encoding: br" -s http://localhost/test/large.html | wc -c

Verify your setup

# Check Apache is running with worker MPM
sudo apache2ctl -M | grep mpm
apache2ctl -V | grep MPM

Verify compression modules are loaded

sudo apache2ctl -M | grep -E "deflate|brotli|expires|cache|headers"

Check server status page

curl http://localhost/server-status

Test compression is working

curl -H "Accept-Encoding: gzip" -I http://localhost/test/large.html | grep -i encoding

Verify cache directory exists and has correct permissions

ls -la /var/cache/apache2/mod_cache_disk/

Check process and thread counts

ps aux | grep apache2 | wc -l

Performance tuning parameters explained

Parameter Function Recommended Value Impact
MaxRequestWorkers Maximum concurrent connections 1024 Higher allows more concurrent users
ThreadsPerChild Threads per Apache process 32 Balance between memory usage and concurrency
DeflateCompressionLevel Gzip compression strength 6 Balance between CPU usage and file size
BrotliCompressionQuality Brotli compression strength 6 Better compression than gzip with similar CPU cost
CacheMaxExpire Maximum cache time 86400 Longer cache reduces server load

Common issues

Symptom Cause Fix
Apache won't start after config changes Configuration syntax errors sudo apache2ctl configtest to check syntax
High memory usage Too many MaxRequestWorkers Reduce MaxRequestWorkers and ThreadsPerChild values
Compression not working Missing Accept-Encoding headers Check client sends Accept-Encoding: gzip, br
Cache directory permission errors Wrong ownership on cache directory sudo chown -R www-data:www-data /var/cache/apache2
Server status page not accessible mod_status not enabled or wrong IP Verify sudo a2enmod status and check IP restrictions
Slow response times under load Insufficient server resources Monitor with htop and adjust worker settings
Cache not working for dynamic content Incorrect cache headers Add Cache-Control headers in application code

Next steps

Automated install script

Run this to automate the entire setup

#apache #performance #caching #compression #mpm #optimization

Need help?

Don't want to manage this yourself?

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

Talk to an engineer