Truc's NotesVol. 1 (2026)

Hybrid Cache with In-Memory + Redis in .NET

Truc Nguyen*

AbstractA quick note on setting up hybrid caching in .NET — combining in-memory (L1) and Redis (L2) for fast, scalable APIs. Includes config, load test results, and trade-offs.

Keywords:tech · c# · dotnet · caching · redis

Hybrid cache = in-memory (L1) + Redis (L2). Reads hit L1 first (fast), then L2, then the data source. Redis keeps the cache consistent across multiple server instances.


How it works

client → L1 (memory) → L2 (redis) → database
         ↑ cache hit   ↑ cache hit  ↑ cache miss
  • L1 (in-memory): fastest. local to each server process.
  • L2 (redis): shared across all server instances. survives restarts.
  • database: only called on a full cache miss.

Setup

Register hybrid cache with Redis as the distributed backend:

builder.Services.AddHybridCache(options =>
{
    options.DefaultEntryOptions = new HybridCacheEntryOptions
    {
        Expiration = TimeSpan.FromMinutes(5),
        LocalCacheExpiration = TimeSpan.FromMinutes(5)
    };
});

builder.Services.AddStackExchangeRedisCache(options =>
{
    options.Configuration = "localhost:6379";
    options.InstanceName = "hybrid-cache-demo";
});

Cache entries expire from both L1 and L2 after 5 minutes.

Sample endpoint

app.MapGet("/v1/categories", async (ILookupService service) =>
{
    var result = await service.GetCategoriesAsync();
    return Results.Ok(result);
});

Load test results

Using bombardier — 10,000 requests, 125 concurrent connections:

Reqs/sec    6937 avg  (peak: 82,646)
Latency     p50: 2.62ms  p95: 4.24ms  p99: 1.36s
HTTP 2xx    10,000 / 10,000
Throughput  2.34 MB/s

The p99 spike (1.36s) is expected — those are cache misses hitting the data source cold.

Trade-offs

  • ✅ Fast reads: L1 hit returns in microseconds
  • ✅ Scalable: Redis shares cache across instances
  • ✅ Simple API: GetOrCreateAsync handles all layers
  • ⚠️ Redis required: Adds infra dependency
  • ⚠️ Brief inconsistency: Each server has its own L1; may serve stale data until L1 expires
  • ⚠️ Cache invalidation: Not trivial — design expiry strategy upfront

References

Cite

@misc{nguyen2026:dotnet-hybrid-caching,
  author = {Nguyen, Truc},
  title  = {Hybrid Cache with In-Memory + Redis in .NET},
  year   = {2026},
  url    = {https://tructn.github.io/blog/dotnet-hybrid-caching},
  note   = {Truc's Notes}
}

← All articles