---
title: Configure cache headers
slug: dxp/cms12-docs/configure-cache-headers
docTags: 
createdAt: 2026-06-01T17:39:49.387Z
---

Using the correct cache headers in your application ensures you get the most out of the CDN service, regardless of whether you want to cache static content, text, or HTML. You can use

:::Iframe{code="<Anchor title=&#x22;Caching in HTTP&#x22; href=&#x22;https://www.w3.org/Protocols/rfc2616/rfc2616-sec13.html&#x22;>"}

:::

Last-Modified, **cache-control** settings, *ETags*, or a combination of these to determine whether content has changed.

## Cache-control

There are many HTTP header settings, but **cache-control** is one of the most important ones because this setting determines how long a cached object should remain.

A CDN monitors the cache headers in the response settings:

- `cache-control: no-cache` – The CDN will *not* cache the content.
- `cache-control: public` –  The CDN caches the content.

:::hint{type="warning"}
**Important**
You must set the `cache-control` to `public`  (not private, which means that only the browser is allowed to cache the content).
:::

Typical values:

- `max-age=$seconds` – Determines the lifespan of an object.
- `must-revalidate`– Tells the cache to follow maximum lifespan information strictly.
- `public` – Can be cached by intermediaries.
- `private` – Can be cached, but only by the browser.

:::hint{type="warning"}
**Caution**
Do not set `cache` to `public` on page requests if the page has private information, such as a cart page in ecommerce.
:::

**Example:** Caching an object for a maximum of 20 minutes.

`Cache-Control: public, max-age=1200, must-revalidate`

## Cache levels for query strings

The default cache layer setting in DXP for query strings is *Standard*, meaning that a different resource is delivered each time the query string changes.

## Cache static content

Use as long `max-age` as possible, at least for static content, to minimize the trips to the web server. In `web.config`, there are specific sections for setting cache headers for static content. You can see an example of settings when you install an Optimizely site through Visual Studio.

The `<staticContent>` tag and the `<clientCache>` subtag set cache headers in the HTTP response. In the following example, static files are cached for one day. The `<staticContent>` section controls caching for the files that are part of the web application code and cannot be changed by editors.

The `<caching>` tag and its subsetting control the IIS cache, which is cached in the web server by IIS. This will not interfere with the cache headers in the HTTP response, so removing the `<caching>` tag will not make a difference to the cache in the CDN.

**Example:** Configuring cache headers for static content.

```xml
<configuration>
   <system.webServer>
     <staticContent>
       <clientCache cacheControlMode="UseMaxAge" 
                    cacheControlMaxAge="1.00:00:00" />
     </staticContent>
     <caching>
       <profiles>
         <add extension=".gif"  
              policy="DontCache" 
              kernelCachePolicy="CacheUntilChange"/>
         <add extension=".png"  
              policy="DontCache" 
              kernelCachePolicy="CacheUntilChange"/>
         <add extension=".js"
              policy="DontCache" 
              kernelCachePolicy="CacheUntilChange"/>
         <add extension=".css"
              policy="DontCache" 
              kernelCachePolicy="CacheUntilChange"/>
         <add extension=".jpg"
              policy="DontCache" 
              kernelCachePolicy="CacheUntilChange"/>
         <add extension=".jpeg"
              policy="DontCache" 
              kernelCachePolicy="CacheUntilChange"/>
       </profiles>
     </caching>
   </system.webServer>
</configuration>
```

## Override SetCachePolicy

If you use `SetMaxAge`, this sets `cache-control` to `public`. The following example sets the `max-age` using a `TimeSpan` of one hour, which is converted automatically to 3600 seconds.

```csharp
public class StartPageController: PageControllerBase {
  public ActionResult Index(StartPage currentPage) {
    Response.Cache.SetCacheability(HttpCacheability.Public);
    Response.Cache.SetMaxAge(TimeSpan.FromHours(1));
    return View(currentPage);
  }
}
```

If you use `SetExpires`, this sets `cache-control` to `public`, and `Expires` to your selected date and time.

```csharp
public class StartPageController: PageControllerBase {
  public ActionResult Index(StartPage currentPage) {
    Response.Cache.SetCacheability(HttpCacheability.Public);
    Response.Cache.SetExpires(DateTime.Now.AddHours(1));
    return View(currentPage);
  }
}
```

## Use ETags

The `ETag` (entity tag) is a part of the HTTP protocol determining cache validation and is best used for *static* content, such as files, uploaded assets, and pages without output caching. You should not use `ETag`s for requests to resources composed from *dynamic* content objects such as a landing page.

You can combine `ETag`s with other settings. You can use Cache-Control `max-age` *and* `ETag`s to fine-tune cache management and optimize performance. You can also use only `ETag`s, if you have specific caching control requirements.

**Recommendations**

- **Static deployed files such as CSS** – Set the expiration date as long as possible, then update the URL to include a version number that changes when new static files are uploaded.
- **Uploaded assets such as images** – ETags are good for this. However, do not set expiration times longer than the editors can wait for a file to be updated because editors may be confused if they upload a new image with the same name and the cache still shows the old image.
- **Custom API controllers and "normal" HTML** – Normally, you should not cache dynamic content, but it may be useful in some cases. Only cache if you do not have personalized content. If an API is cached, ensure variables are pulled from the URI rather than headers to avoid displaying incorrectly cached information and test thoroughly before going live. Do *not* cache *administrative* or *confidential* information.

## Disable ETags

If you need to disable `ETag` headers from the HTTP response, add a `setEtag="false"` attribute setting to the `web.config` file under the application root directory, as in the following example.

```xml
<configuration>
  ...
  <system.webServer>
  ...
    <staticContent>
      <clientCache cacheControlMode="UseMaxAge" 
                   cacheControlMaxAge="1.00:00:00" 
                   setEtag="false" />
    </staticContent>
  ...
  </system.webServer>
  ...
</configuration>
```
