Sending Cache-control Headers Using Apache 2.x and mod_expires

About a year ago I wrote about how use mod_header with Apache 1.3x to send Cache-control headers. It worked so well that I want to configure my Apache 2.x servers to send the same headers. It's even simpler with Apache 2.x since mod_expires is included in most default installs. Here's what I did.

I added a configuration directive for the main server configuration (inside the Directory block) which sends the Cache-control header for common graphics.

<IfModule mod_expires.c>
# turn on the module for this directory
ExpiresActive on

# cache common graphics for 3 days
ExpiresByType image/jpg "access plus 3 days"
ExpiresByType image/gif "access plus 3 days"
ExpiresByType image/jpeg "access plus 3 days"
ExpiresByType image/png "access plus 3 days"

# cache CSS for 24 hours
ExpiresByType text/css "access plus 24 hours"

# set the default to 24 hours
ExpiresDefault "access plus 24 hours"

All that was left was to restart Apache and test everything.

/<your path>/apache2/bin/apachectl configtest
/<your path>/apache2/bin/apachectl restart

Testing was simple. I tailed the access log and made two requests for the same page. The first request resulted with a flurry of files being requested (all the graphics being downloaded). The second request resulted in a single file request (no graphics) and the graphics where logged as HTTP status 304 (unmodified), success.


If cache control headers are present, you will NOT get 304 on a second request. Rather, the browser will use the cached copy without making a request to the web server. A conditional get followed by a 304 is the default behavior when there are no cache control headers.