Isaac.

web

HTTP Caching Strategies

Leverage HTTP caching to improve performance and reduce bandwidth.

By Emem IsaacMay 28, 20233 min read
#http#caching#performance#cdn#headers
Share:

A Simple Analogy

HTTP caching is like keeping frequently used items on your desk. You don't reacquire them from storage; you just grab them.


Why Caching?

  • Speed: Instant responses
  • Bandwidth: Reduce network traffic
  • Server load: Fewer requests
  • User experience: Faster page loads
  • Reliability: Works offline

Cache Headers

// Set cache policy
app.MapGet("/api/products/{id}", async (int id) => 
{
    var product = await GetProductAsync(id);
    return Results.Ok(product);
})
.WithName("GetProduct")
.WithOpenApi()
.CacheOutput(policy => policy
    .Expire(TimeSpan.FromHours(1))
    .Tag("products")
);

// Or manual headers
app.MapGet("/static/file", () =>
{
    return Results.File("file.txt", "text/plain")
        .WithHeaders(h => 
        {
            h.CacheControl = "public, max-age=3600";
            h.ETag = "\"abc123\"";
            h.Expires = DateTimeOffset.UtcNow.AddHours(1);
        });
});

Cache-Control Directives

// Public cache (CDNs and browsers)
Cache-Control: public, max-age=3600

// Private cache (browser only)
Cache-Control: private, max-age=3600

// No caching
Cache-Control: no-cache, no-store

// Revalidate before using
Cache-Control: public, max-age=3600, must-revalidate

Example in code:

response.Headers.CacheControl = "public, max-age=3600, must-revalidate";

ETags and Validation

app.MapGet("/api/data", async (HttpContext context) =>
{
    var data = await GetDataAsync();
    var etag = "\"data-v123\"";
    
    // Client has fresh copy?
    if (context.Request.Headers.IfNoneMatch == etag)
    {
        return Results.StatusCode(304);  // Not Modified
    }
    
    context.Response.Headers.ETag = etag;
    context.Response.Headers.CacheControl = "max-age=3600";
    
    return Results.Ok(data);
});

Conditional Requests

// Last-Modified
app.MapGet("/file", async (HttpContext context) =>
{
    var lastModified = new DateTimeOffset(2025, 1, 1, 0, 0, 0, TimeSpan.Zero);
    
    if (context.Request.Headers.IfModifiedSince.Count > 0)
    {
        var clientTime = DateTimeOffset.Parse(context.Request.Headers.IfModifiedSince);
        if (clientTime >= lastModified)
        {
            return Results.StatusCode(304);  // Not Modified
        }
    }
    
    var file = await GetFileAsync();
    context.Response.Headers.LastModified = lastModified.ToString("r");
    context.Response.Headers.CacheControl = "max-age=86400";
    
    return Results.File(file, "application/octet-stream");
});

Distributed Caching

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

app.MapGet("/api/expensive", async (
    IDistributedCache cache,
    HttpContext context) =>
{
    const string cacheKey = "expensive-data";
    
    // Try cache first
    var cachedData = await cache.GetAsync(cacheKey);
    if (cachedData != null)
    {
        return Results.Ok(System.Text.Encoding.UTF8.GetString(cachedData));
    }
    
    // Compute if not cached
    var data = await ExpensiveComputationAsync();
    var bytes = System.Text.Encoding.UTF8.GetBytes(data);
    
    // Cache for 1 hour
    await cache.SetAsync(cacheKey, bytes, 
        new DistributedCacheEntryOptions
        {
            AbsoluteExpirationRelativeToNow = TimeSpan.FromHours(1)
        });
    
    return Results.Ok(data);
});

Best Practices

  1. Version assets: Use query params or filenames
  2. Cache busting: Change URLs for new content
  3. Validation: Use ETags and Last-Modified
  4. Security: Cache-Control for sensitive data
  5. Monitoring: Track cache hit rates

Related Concepts

  • CDN strategies
  • Service workers
  • Cache invalidation
  • Browser storage (localStorage, sessionStorage)

Summary

HTTP caching dramatically improves performance through intelligent reuse of responses. Use Cache-Control headers, ETags, and distributed caches for optimal results.

Share:

Written by Emem Isaac

Expert Software Engineer with 15+ years of experience building scalable enterprise applications. Specialized in ASP.NET Core, Azure, Docker, and modern web development. Passionate about sharing knowledge and helping developers grow.

Ready to Build Something Amazing?

Let's discuss your project and explore how my expertise can help you achieve your goals. Free consultation available.

💼 Trusted by 50+ companies worldwide | ⚡ Average response time: 24 hours