.htaccess best practices

Performance, security, and maintainability recommendations for Apache .htaccess files, including when to use httpd.conf instead.

Opinionated recommendations for writing secure, performant, and maintainable .htaccess configurations in Apache HTTP Server.

Use httpd.conf Instead of .htaccess When Possible

Apache HTTP Server reads .htaccess files on every request, which creates per-request file system overhead. Directives placed in httpd.conf or inside a <VirtualHost> block load once at server startup and avoid repeated disk lookups. Move .htaccess directives into the main configuration whenever root access to the server is available.

The httpd.conf file uses <Directory> blocks to apply the same per-directory rules that .htaccess provides. This approach delivers identical functionality without the performance cost of per-request file parsing.

<VirtualHost *:443>
    DocumentRoot "/var/www/example_com/public_html"
    ServerName example.com

    <Directory "/var/www/example_com/public_html">
        Require all granted
        Options +FollowSymLinks -Indexes
    </Directory>

    RewriteEngine On
    RewriteCond %{HTTP_HOST} ^www\.example\.com [NC]
    RewriteRule (.*) https://example.com%{REQUEST_URI} [R=301,L]
</VirtualHost>

Keep .htaccess Files to a Minimum

Apache HTTP Server searches for .htaccess files in every directory along the request path. Multiple .htaccess files increase the number of disk reads per request and make debugging harder. Consolidate all directives into a single .htaccess file in the document root (such as public_html/) whenever possible.

A scattered collection of .htaccess files across nested directories creates inheritance conflicts. A child .htaccess file can silently override a parent's directives, which leads to unexpected behavior that is difficult to diagnose.

Set AllowOverride to the Minimum Required Classes

The AllowOverride All setting in Apache HTTP Server permits every directive category in .htaccess files. Restrict AllowOverride to only the directive classes the site requires. This limits the attack surface if an attacker gains write access to a .htaccess file.

<Directory "/var/www/example_com/public_html">
    AllowOverride AuthConfig FileInfo Options
</Directory>

The AuthConfig class enables authentication directives. The FileInfo class enables mod_rewrite and MIME type directives. The Options class controls directory features such as FollowSymLinks and Indexes. Grant only what the application requires.

Enable HTTP Strict Transport Security (HSTS) in .htaccess

The .htaccess mod_headers module sets the Strict-Transport-Security header, which instructs browsers to use HTTPS exclusively for future requests. HSTS prevents man-in-the-middle attacks and SSL-stripping attacks on sites that serve HTTPS.

<IfModule mod_headers.c>
    Header always set Strict-Transport-Security "max-age=31536000; includeSubDomains"
</IfModule>

The max-age value specifies the duration in seconds. Common values:

DurationSeconds
1 hour3600
1 day86400
7 days604800
30 days2630000
1 year31536000

Remove includeSubDomains if the site has subdomains that do not support HTTPS. Adding includeSubDomains to a site with HTTP-only subdomains breaks access to those subdomains in browsers that enforce HSTS.

Use Apache 2.4 Syntax in .htaccess

Apache HTTP Server 2.4 replaced the Order, Allow, and Deny directives with the Require directive from mod_authz_core. The old directives still function when mod_access_compat is loaded, but they are deprecated. New .htaccess files should use Require exclusively.

Mixing Apache 2.2 and 2.4 access control directives in the same .htaccess file causes unpredictable behavior. Use <IfModule> conditionals only when the same .htaccess file must work across both Apache versions.

Wrap Rewrite Rules in IfModule Checks in .htaccess

The .htaccess <IfModule> directive prevents a 500 Internal Server Error when a required Apache module is not loaded. Wrap mod_rewrite directives in an <IfModule mod_rewrite.c> block so Apache skips the rules gracefully instead of returning an error.

<IfModule mod_rewrite.c>
    RewriteEngine On
    RewriteCond %{HTTPS} !on
    RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L]
</IfModule>

Test .htaccess Changes in a Staging Environment

Apache HTTP Server does not validate .htaccess syntax before applying directives. A single syntax error causes a 500 Internal Server Error for every request to the affected directory. Test .htaccess changes on a staging server or development environment before deploying to production.

Use the apachectl configtest command to validate the main server configuration. This command does not check .htaccess files directly, but it verifies that the modules referenced by .htaccess directives are loaded.

apachectl configtest