Configuring a web caching policy in Apache lets browsers and intermediate proxies, such as a Content Delivery Network (CDN), reuse downloaded resources, which reduces unnecessary network requests. This improves page load speed while decreasing server load and bandwidth consumption.
Disclaimer: This topic may contain information about third-party products. Alibaba Cloud does not make any representations or warranties about the performance or reliability of third-party products. You are responsible for any potential impact from using these products.
Choose an Apache module
Apache module | Pros | Cons | Use cases |
| Simple syntax. Quickly sets expiration times for different file types. | Limited functionality. Cannot set | Setting a simple cache duration ( |
| Provides full control over HTTP headers, supporting all | Its syntax is more complex than | Production environments that require fine-grained and comprehensive caching strategies. |
Procedure
Enable the modules
Before you configure a caching policy, ensure that the headers and expires modules are enabled in Apache.
To check if the modules are loaded, run the
apachectl -Morhttpd -Mcommand. Verify thatheaders_moduleandexpires_moduleare in the output list.Enable the modules:
For Debian/Ubuntu:
sudo a2enmod headers expires sudo systemctl restart apache2For CentOS/RHEL/Alibaba Cloud Linux: These modules are typically compiled or loaded by default. If they are missing, check the configuration files in the
/etc/httpd/conf.modules.d/directory. Make sure theLoadModulelines are not commented out.
Choose a configuration file location
You can store cache configurations in a single file or in the VirtualHost block of your site.
Recommended: Create a new file, such as
cache.conf, in the/etc/httpd/conf.d/directory for CentOS/RHEL or the/etc/apache2/conf-available/directory for Debian/Ubuntu.Not recommended: Avoid making configurations in
.htaccessfiles. Because Apache must read and parse.htaccesson every request, this causes unnecessary performance overhead.
Configuration examples
Set a global default cache expiration time
mod_expires
<IfModule mod_expires.c>
# Enable the mod_expires feature
ExpiresActive On
# Set the default cache time for all resources to 1 day
ExpiresDefault "access plus 1 day"
</IfModule>mod_headers
<IfModule mod_headers.c>
# Set the Cache-Control header. The cache time is 1 day
Header set Cache-Control "max-age=86400, public"
</IfModule>Set caching policies by file type
mod_expires
<IfModule mod_expires.c>
# Enable the mod_expires feature
ExpiresActive On
# Set the default cache time to 1 day
ExpiresDefault "access plus 1 day"
# Cache image resources for 1 month
ExpiresByType image/jpeg "access plus 1 month"
ExpiresByType image/png "access plus 1 month"
ExpiresByType image/gif "access plus 1 month"
ExpiresByType image/svg+xml "access plus 1 month"
# Cache CSS and JS files for 1 week
ExpiresByType text/css "access plus 1 week"
ExpiresByType application/javascript "access plus 1 week"
</IfModule>mod_headers
<IfModule mod_headers.c>
# Cache image resources for 1 month
<FilesMatch "\.(jpg|jpeg|png|gif|svg)$">
Header set Cache-Control "max-age=2592000, public"
</FilesMatch>
# Cache CSS and JS files for 1 week
<FilesMatch "\.(css|js)$">
Header set Cache-Control "max-age=604800, public"
</FilesMatch>
</IfModule>Disable caching for specific resource types
mod_expires
<IfModule mod_expires.c>
# Enable the mod_expires feature
ExpiresActive On
# Do not cache HTML files
ExpiresByType text/html "access plus 0 seconds"
</IfModule>mod_headers
<IfModule mod_headers.c>
# Disable caching for HTML files
<FilesMatch "\.html$">
Header set Cache-Control "no-store, no-cache, must-revalidate"
Header set Pragma "no-cache"
Header set Expires "0"
</FilesMatch>
</IfModule>Set a custom caching policy
Customize a policy using the following syntax rules of mod_expires and mod_headers:
mod_expires
<IfModule mod_expires.c>
ExpiresActive On
ExpiresDefault "base_time plus time_unit"
ExpiresByType mime_type "base_time plus time_unit"
</IfModule>ExpiresActive On: Enables themod_expiresmodule.ExpiresDefault: Sets the default cache time for all resources that do not have a type defined.ExpiresByType: Sets the cache time for a specific Multipurpose Internet Mail Extensions (MIME) type.mime_type: Describes a file's format. It includes a main type and a subtype, separated by a slash, such asimage/jpeg, ortext/html.base_time: The base time for caching. This is usuallyaccess(when the user accesses the file) ormodification(when the file was last modified).time_unit: The time unit, such as:secondsminuteshoursdaysweeksmonthsyears
mod_headers
<IfModule mod_headers.c>
Header set|append|unset header_name "value"
</IfModule>Header set: Sets the value of the specified HTTP header field.Header append: Appends content to the existing value.Header unset: Deletes the specified HTTP header field.header_name: The name of the HTTP header field to operate on, such asCache-ControlorExpires.value: The value to set.
Validate and apply the configuration
After you modify the configuration, check the syntax and then gracefully reload the service to avoid service interruptions.
Check the configuration syntax. Before you apply changes, run a syntax check command to ensure that there are no errors.
CentOS/RHEL/Alibaba Cloud Linux:
sudo httpd -tDebian/Ubuntu:
sudo apache2ctl -t
If the output is
Syntax OK, you can proceed.Apply the configuration (graceful reload recommended).
Use the
reloadcommand to apply the new configuration without dropping existing connections.CentOS/RHEL/Alibaba Cloud Linux:
sudo systemctl reload httpdDebian/Ubuntu:
sudo systemctl reload apache2
Reference: How web caching works
Understanding web caching helps you correctly configuring Apache. Web caching is divided into two main types: strong caching and negotiated caching:
Strong caching: When a browser requests a resource, it first checks its local cache. If the cache is not expired (determined by the
max-agedirective inCache-Controlor theExpiresheader), the browser loads the resource from its local cache without contacting the server. The HTTP status code is typically200 (from disk cache)or200 (from memory cache). This is the most efficient caching method.Negotiated caching: When a strong cache is invalid (expired) or not set, the browser sends a conditional request to the server to check if its cached version is still valid. This process involves these steps:
The browser sends the request with cache identifiers in its headers, such as
If-None-Match(with theETagvalue from the previous response) orIf-Modified-Since(with theLast-Modifieddate from the previous response).The server compares these identifiers with the current version of the resource.
If the resource has not changed, the server returns a
304 Not ModifiedHTTP status code with an empty response body. The browser then continues to use its local, stale copy.If the resource has been updated, the server returns a
200 OKHTTP status code along with the new resource content.
By configuring Apache, you can control the following key HTTP response headers for your caching policy: