Performance - Caching - Response caching middleware

In this article

Configuration

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddResponseCaching();

var app = builder.Build();

app.UseHttpsRedirection();

// UseCors must be called before UseResponseCaching
//app.UseCors();

app.UseResponseCaching();

Warning UseCors must be called before UseResponseCaching when using CORS middleware.

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddResponseCaching();

var app = builder.Build();

app.UseHttpsRedirection();

// UseCors must be called before UseResponseCaching
//app.UseCors();

app.UseResponseCaching();

app.Use(async (context, next) =>
{
    context.Response.GetTypedHeaders().CacheControl =
        new Microsoft.Net.Http.Headers.CacheControlHeaderValue()
        {
            Public = true,
            MaxAge = TimeSpan.FromSeconds(10)
        };
    context.Response.Headers[Microsoft.Net.Http.Headers.HeaderNames.Vary] =
        new string[] { "Accept-Encoding" };

    await next();
});

app.MapGet("/", () => DateTime.Now.Millisecond);

app.Run();

Warning Responses containing content for authenticated clients must be marked as not cacheable to prevent the middleware from storing and serving those responses. See Conditions for caching for details on how the middleware determines if a response is cacheable.

Options

Option Description
MaximumBodySize The largest cacheable size for the response body in bytes. The default value is 64 * 1024 * 1024 (64 MB).
SizeLimit The size limit for the response cache middleware in bytes. The default value is 100 * 1024 * 1024 (100 MB).
UseCaseSensitivePaths Determines if responses are cached on case-sensitive paths. The default value is false.
var builder = WebApplication.CreateBuilder(args);

builder.Services.AddResponseCaching(options =>
{
    options.MaximumBodySize = 1024;
    options.UseCaseSensitivePaths = true;
});

var app = builder.Build();

app.UseHttpsRedirection();

// UseCors must be called before UseResponseCaching
//app.UseCors();

app.UseResponseCaching();

app.Use(async (context, next) =>
{
    context.Response.GetTypedHeaders().CacheControl =
        new Microsoft.Net.Http.Headers.CacheControlHeaderValue()
        {
            Public = true,
            MaxAge = TimeSpan.FromSeconds(10)
        };
    context.Response.Headers[Microsoft.Net.Http.Headers.HeaderNames.Vary] =
        new string[] { "Accept-Encoding" };

    await next(context);
});

app.MapGet("/", () => DateTime.Now.Millisecond);

app.Run();

VaryByQueryKeys

var responseCachingFeature = context.HttpContext.Features.Get<IResponseCachingFeature>();

if (responseCachingFeature != null)
{
    responseCachingFeature.VaryByQueryKeys = new[] { "MyKey" };
}

HTTP headers used by Response Caching Middleware

Header Details
Authorization The response isn't cached if the header exists.
Cache-Control The middleware only considers caching responses marked with the public cache directive. Control caching with the following parameters:
  • max-age
  • max-stale†
  • min-fresh
  • must-revalidate
  • no-cache
  • no-store
  • only-if-cached
  • private
  • public
  • s-maxage
  • proxy-revalidate‡
†If no limit is specified to max-stale, the middleware takes no action.
proxy-revalidate has the same effect as must-revalidate.

For more information, see RFC 9111: Request Directives.
Pragma A Pragma: ```no-cache``` header in the request produces the same effect as Cache-Control: ```no-cache```. This header is overridden by the relevant directives in the Cache-Control header, if present. Considered for backward compatibility with HTTP/1.0.
Set-Cookie The response isn't cached if the header exists. Any middleware in the request processing pipeline that sets one or more cookies prevents the Response Caching Middleware from caching the response (for example, the cookie-based TempData provider).
Vary The Vary header is used to vary the cached response by another header. For example, cache responses by encoding by including the Vary: Accept-Encoding header, which caches responses for requests with headers Accept-Encoding: gzip and Accept-Encoding: text/plain separately. A response with a header value of * is never stored.
Expires A response deemed stale by this header isn't stored or retrieved unless overridden by other Cache-Control headers.
If-None-Match The full response is served from cache if the value isn't * and the ETag of the response doesn't match any of the values provided. Otherwise, a 304 (Not Modified) response is served.
If-Modified-Since If the If-None-Match header isn't present, a full response is served from cache if the cached response date is newer than the value provided. Otherwise, a 304 - Not Modified response is served.
Date When serving from cache, the Date header is set by the middleware if it wasn't provided on the original response.
Content-Length When serving from cache, the Content-Length header is set by the middleware if it wasn't provided on the original response.
Age The Age header sent in the original response is ignored. The middleware computes a new value when serving a cached response.
 - ```max-age```

 - ```max-stale```†

 - min-fresh

 - ```must-revalidate```

 - ```no-cache```

 - ```no-store```

 - only-if-cached

 - ```private```

 - ```public```

 - ```s-maxage```

 - ```proxy-revalidate```‡

Caching respects request Cache-Control directives

Troubleshooting

Conditions for caching

Note The Antiforgery system for generating secure tokens to prevent Cross-Site Request Forgery (CSRF) attacks sets the Cache-Control and Pragma headers to no-cache so that responses aren't cached. For information on how to disable antiforgery tokens for HTML form elements, see Prevent Cross-Site Request Forgery (XSRF/CSRF) attacks in ASP.NET Core.

Additional resources

Ref: Response Caching Middleware in ASP.NET Core