Caching With Apache's mod_cache On Debian Etch - Page 2

2.2 mod_mem_cache

The mod_mem_cache configuration is located in /etc/apache2/mods-available/mem_cache.conf:

vi /etc/apache2/mods-available/mem_cache.conf

<IfModule mod_mem_cache.c>
        CacheEnable mem /
        MCacheSize 4096
        MCacheMaxObjectCount 100
        MCacheMinObjectSize 1
        MCacheMaxObjectSize 2048

This is the default configuration - if you like you can modify it. A list of configuration directives for mod_mem_cache is available here:

Now let's enable mod_cache and mod_mem_cache as follows:

a2enmod cache
a2enmod mem_cache

/etc/init.d/apache2 force-reload

That's it already! With mod_mem_cache, you don't have to clean up any cache directories.


3 Testing

Unfortunately mod_cache doesn't provide any logging functionalities which is bad if you want to know if logging is working. Therefore I create a small PHP test file, /var/www/cachetest.php, that sends out HTTP headers that tell mod_cache that it should cache the file for 300 seconds, and that simply prints the timestamp:

vi /var/www/cachetest.php

header("Cache-Control: must-revalidate, max-age=300");
header("Vary: Accept-Encoding");
echo time()."<br>";

Now call that file in a browser - it should display the current time stamp. Then click in the browser's address bar and press ENTER so that the page gets loaded again (don't press F5 or the reload button - this will always fetch a fresh copy from the server instead of the cache!) - if all goes well, you should still see the old, cached timestamp. If you wait 300 seconds, you should get a fresh copy from the server instead of the cache.


4 HTTP Headers

Caching doesn't work out-of-the-box - you must modify your web application so that caching can work (it is possible that your web application already supports caching - please consult the documentation of your application to find out). mod_cache will cache web pages only if the HTTP headers sent out by your web application tell it to do so.

Here are some examples of headers that tell mod_cache not to cache:

  • Expires headers with a date in the past: "Expires: Sun, 19 Nov 1978 05:00:00 GMT"
  • Certain Cache-Control headers: "Cache-Control: no-store, no-cache, must-revalidate" or "Cache-Control: must-revalidate, max-age=0"
  • Set-Cookie headers: a page will not be cached if a cookie is set.

So if you want mod_cache to cache your pages, modify your application to not send out such headers.

If you want mod_cache to cache your pages, you can set an Expires header with a date in the future, but the recommended way is to use max-age:

"Cache-Control: must-revalidate, max-age=300"

This tells mod_cache to cache the page for 300 seconds (max-age) - unfortunately mod_cache doesn't know the s-maxage option (see, that's why we must use the max-age option (which also tells your browser to cache - please keep this in mind if you get unexpected results!). If mod_cache knew the s-maxage option, we could use "Cache-Control: must-revalidate, max-age=0, s-maxage=300" which would tell mod_cache, but not the browser, to cache the page.

Of course, this header is useless if you send out one of the non-caching headers (Expires in the past, Set-Cookie, etc.) from above at the same time!

Another very important header for caching is this one:

"Vary: Accept-Encoding"

This makes mod_cache keep two copies of each cached page, one compressed (gzip) and one uncompressed so that it can deliver the right version depending on the capabilities of the user-agent/browser. Some user-agents don't understand gzip compression, so they should get the uncompressed version.

So here's the summary: use the following two headers if you want mod_cache to cache:

"Cache-Control: must-revalidate, max-age=300"
"Vary: Accept-Encoding"

and make sure that no Expires with a date in the past, cookies, etc. are sent.

If your application is written in PHP, you can use PHP's header() function to send out HTTP headers, e.g. like this:

header("Cache-Control: must-revalidate, max-age=300");
header("Vary: Accept-Encoding");

This page is a must-read if you want to learn more about HTTP headers and caching:


Falko Timme

About Falko Timme

Falko Timme is an experienced Linux administrator and founder of Timme Hosting, a leading nginx business hosting company in Germany. He is one of the most active authors on HowtoForge since 2005 and one of the core developers of ISPConfig since 2000. He has also contributed to the O'Reilly book "Linux System Administration".

Share this page:

Suggested articles

4 Comment(s)

Add comment


By: Simon Holywell

If you set the Pragma header to no-cache it will also stop mod_cache from caching your webpage.

By: bl0m5t3r

yes it is possible, i use the following statement in my .htaccess

<IfModule mod_headers.c>
# Turn on Expires and set default to 0
ExpiresActive On
ExpiresDefault A0
# Set up caching on media files for 1 year (forever?)
<FilesMatch "\.(flv|ico|pdf|avi|mov|ppt|doc|mp3|wmv|wav)$">
ExpiresDefault A29030400
Header append Cache-Control "public"

# Set up caching on media files for 6 month
<FilesMatch "\.(gif|jpg|jpeg|png|swf)$">
ExpiresDefault A14515200
Header append Cache-Control "public"
# Set up 1 month caching on commonly updated files
<FilesMatch "\.(xml|txt|html|css|js)$">
ExpiresDefault A2419200
Header append Cache-Control "proxy-revalidate"
# Force no caching for dynamic files
#<FilesMatch "\.(php|cgi|pl|htm)$">
#ExpiresActive Off
#Header set Cache-Control "private, no-cache, no-store, proxy-revalidate, no-transform"
#Header set Pragma "no-cache"

I guess with the above example you can adjust it to every one of your sites.

By: Norio

I have multiple sites on my server.  Some can be cached for 10 minutes, others for 1 minute, others for days at a time.  Is it possible to have a separate configuration for each using .htaccess files or something?

By: raghu

The cachetest.php behaves in the same way though i enable or disable mod_cache