Enabling and Configuring mod_expires in Apache for Caching
mod_expires is the Apache module that emits browser-caching headers (Expires and Cache-Control) automatically based on content type. This guide walks through enabling it and the per-MIME-type cache rules you'll actually want. For the related references, see How to Enable and Configure mod_expires in Apache for Caching, Enable mod_headers and Verify That mod_expires is Working in Apache, and How to Specify a Vary: Accept-Encoding Header in Apache.
What is mod_expires?
mod_expires is an Apache module that allows you to control client-side caching using the Expires and Cache-Control headers. This helps:
- Improve website performance by reducing load times.
- Reduce bandwidth usage by caching static assets.
- Enhance SEO and user experience by avoiding unnecessary re-downloads.
Check if mod_expires is Enabled
Run:
apachectl -M | grep expires
Expected output:
expires_module (shared)
If mod_expires is not enabled, proceed to Step 2.
Enable mod_expires in Apache
For Debian/Ubuntu
Run:
sudo a2enmod expires
sudo systemctl restart apache2
For CentOS/RHEL
Ensure mod_expires is loaded in Apache's configuration file:
sudo nano /etc/httpd/conf/httpd.conf
Find or add:
LoadModule expires_module modules/mod_expires.so
Restart Apache:
sudo systemctl restart httpd
Configure mod_expires in Apache
Global Caching for Static Files
Edit your site's Apache configuration file:
sudo nano /etc/apache2/sites-available/000-default.conf
or
sudo nano /etc/httpd/conf/httpd.conf
Add inside the <VirtualHost> block:
<IfModule mod_expires.c>
ExpiresActive On
ExpiresDefault "access plus 1 month"
# Images
ExpiresByType image/jpeg "access plus 6 months"
ExpiresByType image/png "access plus 6 months"
ExpiresByType image/gif "access plus 6 months"
# CSS and JavaScript
ExpiresByType text/css "access plus 1 month"
ExpiresByType text/javascript "access plus 1 month"
ExpiresByType application/javascript "access plus 1 month"
# HTML and XML
ExpiresByType text/html "access plus 1 day"
ExpiresByType application/xml "access plus 1 day"
</IfModule>
What This Does:
- Enables caching for static files (CSS, JS, images).
- Ensures browsers store these files for faster page loading.
Restart Apache:
sudo systemctl restart apache2
or
sudo systemctl restart httpd
Enable Caching in .htaccess
If you cannot modify Apache's main configuration, you can enable caching via .htaccess.
Edit .htaccess File
sudo nano /var/www/html/.htaccess
Add:
<IfModule mod_expires.c>
ExpiresActive On
ExpiresDefault "access plus 1 month"
# Images
ExpiresByType image/jpeg "access plus 6 months"
ExpiresByType image/png "access plus 6 months"
ExpiresByType image/gif "access plus 6 months"
# CSS and JavaScript
ExpiresByType text/css "access plus 1 month"
ExpiresByType text/javascript "access plus 1 month"
ExpiresByType application/javascript "access plus 1 month"
# HTML and XML
ExpiresByType text/html "access plus 1 day"
ExpiresByType application/xml "access plus 1 day"
</IfModule>
Save and exit the file, then restart Apache.
Verify That mod_expires is Working
Check HTTP Headers
Run:
curl -I http://yourdomain.com/path-to-image.jpg
Expected output:
Cache-Control: max-age=15552000
Expires: Tue, 10 Sep 2024 12:00:00 GMT
If the headers do not appear, check Apache logs.
Check Apache Logs for Errors
sudo tail -f /var/log/apache2/error.log
or for CentOS:
sudo tail -f /var/log/httpd/error_log
Summary of Fixes
| Issue | Fix |
|---|---|
| mod_expires not enabled | sudo a2enmod expires (Debian) or LoadModule expires_module (CentOS) |
| No caching headers in response | Add rules in Apache config or .htaccess |
| Changes not applying | Restart Apache: sudo systemctl restart apache2 |
| Debug headers | Use curl -I http://yourdomain.com |
By enabling and configuring mod_expires, you reduce load times, improve performance, and enhance user experience.
