Caching in Apache makes repeated requests cheaper by serving eligible responses from a local cache instead of regenerating them each time. A cache hit is the closest thing to free performance: lower latency for clients, lower load for the server, and fewer spikes that turn “fine” into “fire drill”. Static assets like CSS, JavaScript, fonts, and images usually benefit the most.
HTTP-aware caching in Apache is handled by mod_cache plus a storage provider such as mod_cache_socache (shared-object cache) or mod_cache_disk (disk cache). Caching is enabled for a specific URL space via CacheEnable, and cacheability is driven by standard HTTP rules (for example Cache-Control and Expires), not by blindly storing every response.
Cache scope matters more than cache size: caching personalized or authenticated content can leak private data or serve stale pages to the wrong client. The socache backend is shared-memory oriented, so entries are size-limited and large objects may be skipped; disk caching is a better fit for bigger files. Commands and paths below use the Ubuntu and Debian apache2 layout under /etc/apache2/.
Related: How to enable or disable Apache modules
Related: How to test your Apache configuration
Steps to enable and configure caching in Apache:
- Enable the required caching modules in Apache.
$ sudo a2enmod cache cache_socache socache_shmcb expires headers Enabling module cache. Enabling module cache_socache. Enabling module socache_shmcb. Enabling module expires. Enabling module headers. To activate the new configuration, you need to run: systemctl restart apache2
Systems with a2enmod support can enable modules without manually editing LoadModule directives.
- Open the Apache configuration file in a text editor.
$ sudo vi /etc/apache2/apache2.conf
Related: Location for Apache configuration
- Add the required directives to enable and configure caching.
<IfModule mod_cache.c> CacheQuickHandler off CacheLock on CacheLockPath "/tmp/mod_cache-lock" CacheLockMaxAge 5 CacheHeader on <IfModule mod_cache_socache.c> CacheSocache shmcb:/var/cache/apache2/mod_cache_socache(20971520) CacheSocacheMaxSize 512000 CacheSocacheMaxTime 86400 <LocationMatch "\.(css|js|mjs|png|jpe?g|gif|svg|webp|ico|woff2?)$"> CacheEnable socache </LocationMatch> </IfModule> </IfModule>
Limit CacheEnable rules to public content, because cached responses can serve stale or private data if applied to personalized or authenticated URLs.
Directive Description CacheEnable Enables caching for a URL space using a cache type such as socache. CacheSocache Selects the socache provider and its arguments, such as shmcb:/var/cache/apache2/mod_cache_socache(20971520) to allocate a shared-memory cache in bytes. CacheSocacheMaxSize Sets the maximum size (in bytes) of a single cached entry (headers + body). CacheSocacheMaxTime Sets the maximum freshness lifetime (in seconds) of entries stored in socache. CacheHeader Adds an X-Cache response header showing HIT, MISS, or REVALIDATE. CacheLock Enables a per-URL lock to reduce backend stampedes while an entry is being filled or refreshed. CacheQuickHandler Controls whether cached responses are served early in the request pipeline. - Set up cache control headers in .htaccess or a virtual host file for more granular control.
<IfModule mod_expires.c> <FilesMatch "\.(css|js|mjs|png|jpe?g|gif|svg|webp|ico|woff2?)$"> ExpiresActive On ExpiresDefault "access plus 1 month" </FilesMatch> </IfModule>
Rules in .htaccess are ignored unless the relevant /<Directory>/ section permits AllowOverride for the required directive categories.
- Test the Apache configuration for syntax errors.
$ sudo apachectl configtest Syntax OK
- Restart Apache to apply the changes.
$ sudo systemctl restart apache2
Distributions using the httpd service name can restart using systemctl restart httpd.
- Request a cacheable resource once to prime the cache.
$ curl -I https://www.example.com/image.png HTTP/1.1 200 OK Date: Sat, 13 Dec 2025 09:13:40 GMT Server: Apache Last-Modified: Sat, 13 Dec 2025 08:57:56 GMT ETag: "1f61-603bb8a696d78" Content-Type: image/png Content-Length: 8033 Cache-Control: max-age=2592000 Expires: Mon, 12 Jan 2026 09:13:40 GMT X-Cache: MISS from localhost
MISS is expected on the first request after a restart, because the cache starts empty.
- Request the same resource again.
$ curl -I https://www.example.com/image.png HTTP/1.1 200 OK Date: Sat, 13 Dec 2025 09:13:42 GMT Server: Apache Age: 2 Content-Type: image/png X-Cache: HIT from localhost ##### snipped #####
If X-Cache never changes to HIT, confirm the response is not marked no-store or private and matches the configured LocationMatch patterns.
Disable cache debug headers after validation by setting CacheHeader to off.
Mohd Shakir Zakaria is a cloud architect with deep roots in software development and open-source advocacy. Certified in AWS, Red Hat, VMware, ITIL, and Linux, he specializes in designing and managing robust cloud and on-premises infrastructures.
Comment anonymously. Login not required.
