Invite-only beta · 10 places · Managed hosting on AWS

AceMedia HostRequest invite

HOSTING TIPS · 2 OCTOBER 2026

Apache tips for a faster, safer site

Apache still runs a huge share of the web, and a few changes to its defaults make it noticeably faster and harder to poke at. Most take a minute each.

Apache tuning starts with how the server handles requests, runs PHP and serves static files. I check those boundaries before raising worker limits or adding modules. The steps below cover the settings I review, how to check them and where the site’s own configuration needs to take precedence.

Swap mod_php for PHP-FPM and the event MPM

The old prefork model starts a heavy process for every connection, and mod_php loads PHP into all of them, even the ones serving images. The event MPM with PHP-FPM handles far more visitors on the same memory:

sudo apt install php8.3-fpm
sudo a2dismod php8.3 mpm_prefork
sudo a2enmod mpm_event proxy_fcgi setenvif
sudo a2enconf php8.3-fpm
sudo apachectl configtest && sudo systemctl restart apache2

Use your installed PHP version in place of 8.3. Check with apachectl -V | grep MPM afterwards.

Turn on HTTP/2 and Brotli

sudo a2enmod http2 brotli headers expires
sudo systemctl reload apache2
Protocols h2 http/1.1

<IfModule mod_brotli.c>
    AddOutputFilterByType BROTLI_COMPRESS text/html text/css text/plain \
        application/javascript application/json image/svg+xml
</IfModule>

HTTP/2 needs the event or worker MPM, which is one more reason to make the switch above.

Cache static files properly

If your CSS and JavaScript URLs change when the files change, such as style.css?v=42 or a hashed filename, browsers can keep them for a year:

<IfModule mod_headers.c>
    <FilesMatch "\.(css|js|svg|woff2|png|jpe?g|webp|avif)$">
        Header set Cache-Control "public, max-age=31536000, immutable"
    </FilesMatch>
</IfModule>

Only do this for versioned assets. If you edit a file and the URL stays the same, visitors will keep the old one for a year.

See real visitor addresses behind Cloudflare

Behind a proxy, Apache logs the proxy’s address for every visitor. mod_remoteip fixes that, but trust the header only from the proxy itself, or anyone can fake their address:

RemoteIPHeader CF-Connecting-IP
RemoteIPTrustedProxy 173.245.48.0/20
RemoteIPTrustedProxy 103.21.244.0/22
# ...one line for each range at https://www.cloudflare.com/ips/

# Log the real address
LogFormat "%a %l %u %t \"%r\" %>s %O \"%{Referer}i\" \"%{User-Agent}i\"" combined
sudo a2enmod remoteip && sudo apachectl configtest && sudo apachectl graceful

Say less about yourself

# /etc/apache2/conf-available/security.conf
ServerTokens Prod
ServerSignature Off
TraceEnable Off

Never serve what should stay private

Deploying from Git can leave scripts, notes, dumps and the .git folder sitting in the web root. Refuse them outright:

<FilesMatch "\.(sql|bak|env|log|sh|yml|yaml|md|dist)$|^(composer|package)\.(json|lock)$">
    Require all denied
</FilesMatch>
<DirectoryMatch "/\.git">
    Require all denied
</DirectoryMatch>

Skip .htaccess when you own the config

With AllowOverride All, Apache checks for an .htaccess file in every folder on every request. If you control the virtual host, move the rules there and switch lookups off:

<Directory /var/www/example>
    AllowOverride None
    Require all granted
    # WordPress permalinks, moved from .htaccess
    RewriteEngine On
    RewriteRule ^index\.php$ - [L]
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteRule . /index.php [L]
</Directory>

Test before you reload, every time

sudo apachectl configtest && sudo apachectl graceful

# What is loaded, and which site answers which name
apachectl -M
apachectl -S

A graceful reload lets current visitors finish while new requests get the new config. A failed config test means nothing changes, which is exactly what you want.

More hosting tipsTalk about your hosting

LET’S TALK

Want a server set up like this?

We run sites on a stack built with these habits. Tell us about yours and we’ll give you a straight answer about fit.

Ask for an invite

INVITE-ONLY BETA

Tell us about your site.

We’re inviting ten beta projects to help us test and shape the service. Tell us what you’re building; we’ll reply personally. Fields marked * are required.

Please do not send passwords or private customer data. We’ll use these details to reply. Privacy notice.

Prefer email? Write to [email protected].