IIS7 StaticContent and ClientCache Settings

Yet another great feature of IIS7  - declarative static content cache settings. It took a little detective work to find the settings for this feature – including a helpful post from Jörg Jooss.

I wanted to be able to set the client cache settings for the static content of a site I host at ORCS Web. In the past – unless offered by the control panel of your shared hosting provider – this would have meant emailing support and asking them to set the client cache header settings for the required directory in IIS6. In IIS7 this can be set now in the <system.webserver> section.

Note: If you’re going to try this on your local machine first, you will need to unlock the staticContent section in IIS7 (from the machine level) using the following appcmd…

appcmd unlock config /section:staticContent

You can also use appcmd to create the static content cache settings as shown in Jörg’s post above, which will add the correct section to your web.config – or you can directly edit/create the web.config file for the required directory.

I chose to hand edit the web.config – creating a new web.config located in the directory with the static content (i.e. images, style sheets, script files – all under the ‘assets’ directory in my case)

<?xml version="1.0"?>
<configuration>
  <system.webServer>
    <staticContent>
      <clientCache cacheControlCustom="private" cacheControlMode="UseMaxAge" cacheControlMaxAge="3.00:00:00" />
    </staticContent>
  </system.webServer>
</configuration>

A couple of things to note about these settings. Firstly – you can add any custom cache control header setting using the cacheControlCustom attribute (e.g. no-store, must-revalidate, private, public etc). Secondly using the http 1.1 max-age setting – you can specify days – by using the 1.00 notation for the hours portion of the hh:mm:ss timespan value. So the setting above will set the max-age value to 3 days – or 259200 seconds when you see it in the response header.

Category

Comments

Thanks for posting this. Very difficult to find how to set Cache-Control: public in IIS7 - and the MSDN docs are just confusing.

For what it's worth, "Google Page Speed" recommends cache settings that look like this on IIS7:
(tag characters removed to avoid ASP.Net's built-in Validation from erroring out on this server)

clientCache cacheControlCustom="public" cacheControlMode="UseMaxAge" cacheControlMaxAge="365.00:00:00"/

But this leaves 2 caveats:
1) The default config for Javascript is to serve .js files as dynamic files, not static, so they won't end up being cached by this config unless you add them as a staticContent type.

2) If you don't use URL fingerprinting (for example if an image changes, name it imageName-2010-02-11.jpg), these cache settings can end up leaving past visitors with cached versions of new content like images, css, js, and worst, html files. You need to either live with a short cache time, or come up with a URL fingerprinting scheme that works for you (manually, use a CMS, etc).

Thanks for the comment - good points - and I agree - the IIS7 docs take some detective work to figure out.

using location and webserver is valid ?

< location path="Images" >
< system.webServer>
< staticContent>
< clientCache cacheControlCustom="public" cacheControlMode="UseMaxAge" cacheControlMaxAge="30.00:00:00" / >
< /staticContent>
< / system.webServer>
< / location>
< location path="Js" >
< system.webServer>
< staticContent>
<clientCache cacheControlCustom="public" cacheControlMode="UseMaxAge" cacheControlMaxAge="30.00:00:00" / >
< / staticContent>
< /system.webServer >
< / location >