Saturday, February 21, 2026

Web API - Caching

Note: Response/Output cache handled by their respective middlewares and do not hit controller in subsequent requests until cache invalidated.
Data Cache (IMemorycache, Memcache, Redis): Managed by code, you check in code if data available in cache then serve else reproduce and serve.

1. Output Caching (Recommended for .NET 7+)

Starting in ASP.NET Core 7+, Microsoft introduced built-in Output Caching Middleware, which is the best way to cache full API responses.

Step 1: Register Output Caching

In Program.cs:

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddOutputCache();

var app = builder.Build();

app.UseOutputCache();

app.MapControllers();

app.Run();

Step 2: Apply Caching to an Endpoint
[HttpGet]
[OutputCache(Duration = 60)]
public IActionResult GetProducts()
{
return Ok(GetProductsFromDatabase());
}

🔹 This caches the response for 60 seconds.
🔹 Works great for GET endpoints.


Advanced Example (Custom Policy)
builder.Services.AddOutputCache(options =>
{
options.AddPolicy("MyPolicy", policy =>
policy.Expire(TimeSpan.FromMinutes(5))
.SetVaryByQuery("category"));
});

Then:

[OutputCache(PolicyName = "MyPolicy")]

2. Response Caching (HTTP Cache Headers)

This uses HTTP headers like Cache-Control. It works with browser/proxy caching.

Enable Middleware
builder.Services.AddResponseCaching();
app.UseResponseCaching();
Use Attribute
[ResponseCache(Duration = 60)]
[HttpGet]
public IActionResult GetProducts()
{
return Ok(data);
}

🔹 This sets HTTP headers.
🔹 It does NOT cache on the server by default.
🔹 Good for public APIs.


3. Data Cache 
In-Memory Caching (IMemoryCache)

Best when you want to cache data, not full HTTP responses.

Register
builder.Services.AddMemoryCache();
Use in Controller
private readonly IMemoryCache _cache;

public ProductsController(IMemoryCache cache)
{
_cache = cache;
}

[HttpGet]
public IActionResult GetProducts()
{
if (!_cache.TryGetValue("products", out List<Product> products))
{
products = GetProductsFromDatabase();

var cacheOptions = new MemoryCacheEntryOptions()
.SetSlidingExpiration(TimeSpan.FromMinutes(5));

_cache.Set("products", products, cacheOptions);
}

return Ok(products);
}

4. Distributed Caching (Redis, SQL Server)

For multi-server environments, use distributed cache.

Common choice:

  • Redis: Redis can store complex data types like Lists, arrays, Hash tables etc.

  • Memcached: Simple text string store 

Example Setup with Redis
builder.Services.AddStackExchangeRedisCache(options =>
{
options.Configuration = "localhost:6379";
});

Then inject IDistributedCache.


FeatureMemcachedRedis
DistributedYesYes
ReplicationNo (basic)Yes
PersistenceNoYes
Data loss riskHigherLower
ComplexitySimpleAdvanced



Which One Should You Use?

ScenarioRecommended
Cache full API response    OutputCache
Scale across multiple servers    Redis (Distributed Cache)
Cache DB results only    IMemoryCache
Browser/proxy caching    ResponseCache

Best Practice Tips
  • Cache only GET requests.
  • Avoid caching user-specific data unless using VaryBy.
  • Always define expiration.
  • Invalidate cache on data update.
  • Use distributed cache in production with multiple instances.

Output cache and Response Cache both stores whole response handled by middleware, only difference is storage location. 

Response Caching vs Output Caching
FeatureResponse CachingOutput Caching
Where caching happensClient / Proxy (browser, CDN)Server (inside ASP.NET Core)
MiddlewareUseResponseCaching()UseOutputCache()
Actually stores response on server?NoYes
Performance benefit for serverMinimalSignificant
Best forPublic APIsHigh-performance APIs
IntroducedEarly ASP.NET Core versions.NET 7

No comments:

Post a Comment

Node | Cluster Vs Worker Threads

Cluster: Multiple processes (scale app across CPU cores) Worker Threads: Multiple threads (handle CPU-heavy work inside one process) Cluster...