ASP.NET Core 7+ Output Caching Configuration: Complete Guide to In-Memory and Redis Storage
ASP.NET Core 7+ output caching configuration requires calling AddOutputCache() in Program.cs, inserting UseOutputCache() into the middleware pipeline, and applying the [OutputCache] attribute or IOutputCacheFeature to endpoints, with optional Redis backing via AddStackExchangeRedisOutputCache.
ASP.NET Core 7 introduces a built-in output caching middleware that caches complete HTTP responses—including status codes, headers, and response bodies—to eliminate redundant MVC pipeline executions on repeat requests. According to the dotnet/aspnetcore source code, this middleware is implemented in OutputCacheMiddleware.cs and configured through OutputCacheOptions, supporting both in-memory storage and distributed Redis backends. Proper configuration of ASP.NET Core 7+ output caching enables dramatic latency reductions while maintaining flexible cache invalidation and vary-by rules.
Core Components of the Output Caching System
The output caching middleware consists of several interconnected services defined in the src/Middleware/OutputCaching/src/ directory:
OutputCacheMiddleware– The core pipeline component that intercepts requests, generates cache keys, and serves stored responses fromsrc/Middleware/OutputCaching/src/OutputCacheMiddleware.cs.OutputCacheOptions– Global configuration for size limits, default expiration, and vary-by rules located insrc/Middleware/OutputCaching/src/OutputCacheOptions.cs.OutputCacheAttribute– Declarative metadata for per-endpoint cache policies including duration and vary-by parameters insrc/Middleware/OutputCaching/src/OutputCacheAttribute.cs.IOutputCacheFeature– Runtime API for programmatic cache control and tagging accessed viaHttpContext.Featuresinsrc/Middleware/OutputCaching/src/IOutputCacheFeature.cs.IOutputCachePolicyProvider– Service for resolving named cache policies defined insrc/Middleware/OutputCaching/src/IOutputCachePolicyProvider.cs.
How the Output Caching Pipeline Works
The middleware follows a specific execution flow defined in the dotnet/aspnetcore implementation:
- Registration Phase –
AddOutputCache()registers the in-memory store, policy provider, and supporting services in the dependency injection container. - Pipeline Insertion –
UseOutputCache()must appear early in the middleware pipeline, typically before authentication and authorization components if cached responses should bypass those checks. - Cache Key Generation – For incoming requests, the middleware constructs a cache key from the request path, query string values (based on
VaryByQueryKeys), and specified headers. - Lookup and Short-Circuit – If a matching entry exists, the middleware writes the stored status code, headers, and body directly to the response and terminates the pipeline.
- Storage and Tagging – For cache misses, the request proceeds to the endpoint. After response generation, the middleware stores the response if cacheable (status 200-299, no
Cache-Control: no-store, non-streaming), applying tags viaIOutputCacheFeaturefor later invalidation.
Configuring Output Caching in Program.cs
Registering the Middleware
Add the output caching services to your application builder and insert the middleware into the pipeline:
var builder = WebApplication.CreateBuilder(args);
// Register output caching with in-memory storage
builder.Services.AddOutputCache(options =>
{
options.MaximumBodySize = 100 * 1024 * 1024; // 100 MB limit
options.MaximumResponseCount = 1000; // LRU eviction threshold
options.DefaultExpirationTimeSpan = TimeSpan.FromSeconds(30);
});
var app = builder.Build();
// Insert before components you want to skip on cache hits
app.UseOutputCache();
app.MapControllers(); // or MapGet, MapRazorPages, etc.
app.Run();
Place UseOutputCache() before UseAuthentication() or UseAuthorization() only if you want cached responses to bypass authentication checks. For authenticated endpoints, place authentication middleware before the cache middleware.
Global Configuration Options
The OutputCacheOptions class in src/Middleware/OutputCaching/src/OutputCacheOptions.cs exposes these key properties:
MaximumBodySize– Maximum response body size in bytes that can be cached (default 64 MB).DefaultExpirationTimeSpan– Default cache duration when not specified per-endpoint.VaryByHeaderNames– Global headers to include in cache key generation.Policies– Collection of named policies accessible viaIOutputCachePolicyProvider.
Configuring Redis Distributed Output Caching
For multi-instance deployments, replace the in-memory store with Redis using the Microsoft.AspNetCore.OutputCaching.StackExchangeRedis package:
builder.Services.AddStackExchangeRedisOutputCache(redisOptions =>
{
redisOptions.Configuration = "localhost:6379";
redisOptions.InstanceName = "AspNetCoreCache:";
});
This extension method is defined in src/Middleware/Microsoft.AspNetCore.OutputCaching.StackExchangeRedis/src/StackExchangeRedisCacheServiceCollectionExtensions.cs and utilizes RedisOutputCacheOptions from src/Middleware/Microsoft.AspNetCore.OutputCaching.StackExchangeRedis/src/RedisOutputCacheOptions.cs for connection configuration. When Redis is configured, IOutputCacheService methods work transparently across all instances, with entries serialized using MessagePack.
Endpoint-Level Caching Configuration
Using the OutputCache Attribute
Apply the [OutputCache] attribute to controllers, actions, or minimal API endpoints to override global settings:
using Microsoft.AspNetCore.OutputCaching;
[ApiController]
[Route("api/[controller]")]
public class ProductsController : ControllerBase
{
// Cache for 60 seconds, vary by "category" query string
[HttpGet]
[OutputCache(Duration = 60, VaryByQueryKeys = new[] { "category" }, Tags = new[] { "products" })]
public async Task<IActionResult> Get([FromQuery] string category)
{
return Ok(await _repository.GetByCategoryAsync(category));
}
}
The OutputCacheAttribute in src/Middleware/OutputCaching/src/OutputCacheAttribute.cs supports:
Duration– Cache lifetime in seconds.VaryByQueryKeys– Array of query parameter names to include in the cache key.VaryByHeaderNames– Header names that affect cache key uniqueness (e.g.,Accept-Language).Tags– String tags for bulk invalidation viaIOutputCacheService.EvictByTagAsync().NoStore– Boolean to disable caching for specific endpoints.
Programmatic Cache Control
For dynamic cache metadata, use IOutputCacheFeature inside your endpoint logic:
app.MapGet("/products/{id}", async (int id, HttpContext context, IOutputCacheService cacheService) =>
{
var feature = context.Features.Get<IOutputCacheFeature>();
// Add runtime tags for cache invalidation
feature?.AddTag("products");
feature?.AddTag($"product-{id}");
return Results.Ok(await GetProductAsync(id));
});
Invalidate entries by tag programmatically:
await cacheService.EvictByTagAsync("products");
Advanced Configuration Patterns
Custom Cache Policies
Define reusable named policies by configuring OutputCacheOptions:
builder.Services.AddOutputCache(options =>
{
options.AddPolicy("LongCache", policy =>
{
policy.Expire(TimeSpan.FromMinutes(5));
policy.VaryByQuery("version");
});
});
Apply policies by name: [OutputCache(PolicyName = "LongCache")].
Cache Size Management
The in-memory implementation enforces LRU (Least Recently Used) eviction when limits are exceeded. Control these boundaries via:
MaximumResponseCount– Total number of entries stored across all endpoints.MaximumBodySize– Per-entry size limit to prevent memory exhaustion from large responses.
Summary
- ASP.NET Core 7+ output caching caches complete HTTP responses in memory or Redis to bypass expensive endpoint execution.
- Configuration requires
AddOutputCache()for service registration andUseOutputCache()for pipeline insertion, with optional Redis setup viaAddStackExchangeRedisOutputCache. - Per-endpoint control uses the
[OutputCache]attribute fromsrc/Middleware/OutputCaching/src/OutputCacheAttribute.csfor declarative settings orIOutputCacheFeaturefor runtime tagging. - Invalidation operates via tags using
IOutputCacheService.EvictByTagAsync(), enabling targeted cache clearing across distributed instances. - Source files in
dotnet/aspnetcoresuch asOutputCacheMiddleware.cs,OutputCacheOptions.cs, andRedisOutputCacheOptions.csdefine the implementation details for customization and debugging.
Frequently Asked Questions
What is the difference between output caching and response caching in ASP.NET Core?
Output caching (ASP.NET Core 7+) stores the complete rendered response on the server and bypasses the entire request pipeline on cache hits, while response caching (via [ResponseCache] attribute) primarily sets HTTP headers to instruct clients and proxies to cache. Output caching is server-side and can cache responses for authenticated requests, whereas response caching depends on client cooperation.
How do I invalidate cached responses in ASP.NET Core 7+?
Use the IOutputCacheService interface and call EvictByTagAsync("tag-name") to remove all entries marked with that specific tag. You can also add tags programmatically via IOutputCacheFeature.AddTag() during request processing to enable granular invalidation groups.
Can I use output caching with authenticated endpoints?
Yes, but you must place UseOutputCache() after UseAuthentication() and UseAuthorization() in the middleware pipeline. This ensures the cache key includes the authenticated user context (via VaryByHeaderNames or custom key providers) and prevents serving cached responses to unauthenticated users.
How do I configure output caching to store responses larger than 64 MB?
Set the MaximumBodySize property in OutputCacheOptions during service registration: options.MaximumBodySize = 100 * 1024 * 1024 for 100 MB. Be aware that extremely large cached responses consume significant memory or Redis bandwidth, so consider implementing custom IOutputCacheKeyProvider logic to segment large resources.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →