Introduction
Output caching (.NET 8) caches entire endpoint responses — faster than manual IMemoryCache in controllers for ShopNest news and product list APIs.
After this article you will
- Use [OutputCache] attribute and profiles
- Vary cache by query, headers, user
- Invalidate with cache tags
- Distributed output cache with Redis
- Know when NOT to cache
Prerequisites
- Article 73 — Rate Limiting
- Articles 1–64 ShopNest foundations (MVC, EF Core, API, auth, deploy)
Architecture & design
builder.Services.AddOutputCache(options =>
{
options.AddBasePolicy(b => b.Expire(TimeSpan.FromSeconds(30)));
options.AddPolicy("NewsList", b => b
.Expire(TimeSpan.FromMinutes(2))
.SetVaryByQuery("page", "category")
.Tag("news"));
});
app.UseOutputCache();
[OutputCache(PolicyName = "NewsList")]
[HttpGet("news")]
public async Task<IActionResult> GetNews() => Ok(await _news.GetPageAsync());
// Invalidate on publish
_outputCacheStore.EvictByTagAsync("news", ct);
Output vs Response caching: Output caching is server-side store with tag invalidation — more flexible than older response caching middleware.
Hands-on build guide — ShopNest High-Traffic News API
- OutputCache on GET /api/v1/news.
- Benchmark p95 before/after (Article 57 k6).
- Evict tag on admin POST new article.
- Redis distributed cache for farm.
Common pitfalls
- Caching authenticated personalized feed with public policy — data leak.
- No tag eviction — stale news until TTL expires.
Interview & portfolio questions
Q: Output vs IMemoryCache in action?
A: Output cache at middleware level — no controller code; automatic for GET.
Summary
- OutputCache simplifies high-traffic read endpoints
- Tags enable surgical invalidation on content publish
- Combine with rate limiting for public API protection
Previous: Rate Limiting
Next: .NET 9 New Features
FAQ
Cache POST responses?
No — output caching for safe GET/HEAD only.
CDN vs output cache?
CDN at edge; output cache at origin — both can stack.