Courses/C#/Caching Strategies

    Caching Strategies (MemoryCache, Distributed Cache, Redis)

    Speed up your .NET applications by serving data from fast caches instead of hitting the database on every request.

    What You'll Learn

    • • In-memory caching with IMemoryCache
    • • Sliding vs absolute expiration strategies
    • • Distributed caching with Redis via IDistributedCache
    • • Cache invalidation and the GetOrCreateAsync pattern

    🍽️ Real-World Analogy

    In-memory cache is like keeping today's specials on a whiteboard at the kitchen counter — instant to read but lost if the kitchen closes. Distributed cache (Redis) is like a shared recipe binder in a chain of restaurants — every location reads from the same source, and updates propagate to all kitchens.

    In-Memory Caching with IMemoryCache

    IMemoryCache stores data in the application's memory. It's the fastest cache option but is lost on restart and isn't shared across servers. Use sliding expiration to keep frequently accessed items alive, and absolute expiration to set a hard limit.

    IMemoryCache with Expiration & Eviction

    Cache products with sliding and absolute expiration, plus eviction callbacks.

    Try it Yourself »
    C#
    using Microsoft.Extensions.Caching.Memory;
    
    // Program.cs — register IMemoryCache
    builder.Services.AddMemoryCache();
    
    // ProductService.cs
    public class ProductService
    {
        private readonly IMemoryCache _cache;
        private readonly AppDbContext _db;
    
        public ProductService(IMemoryCache cache, AppDbContext db)
        {
            _cache = cache;
            _db = db;
        }
    
        public async Task<Product?> GetProductAsync(int id)
        {
            string cacheKey = $"product_{id}";
    
            // Try get from c
    ...

    The GetOrCreateAsync Pattern

    GetOrCreateAsync is the cleanest caching pattern — it checks the cache, and if the item doesn't exist, runs your factory delegate to create it. Thread-safe and concise.

    GetOrCreateAsync Pattern

    Use the elegant GetOrCreate pattern for thread-safe cache population.

    Try it Yourself »
    C#
    using Microsoft.Extensions.Caching.Memory;
    
    public class CategoryService
    {
        private readonly IMemoryCache _cache;
        private readonly AppDbContext _db;
    
        public CategoryService(IMemoryCache cache, AppDbContext db)
        {
            _cache = cache;
            _db = db;
        }
    
        // GetOrCreateAsync — elegant pattern
        public async Task<List<Category>> GetAllCategoriesAsync()
        {
            return await _cache.GetOrCreateAsync("all_categories", async entry =>
            {
                entry.SetAbsol
    ...

    Distributed Caching with Redis

    When your app runs on multiple servers, in-memory cache isn't shared. IDistributedCache with Redis gives you a shared, persistent cache that survives restarts. You can also use response caching to cache entire HTTP responses.

    Redis Distributed Cache & Response Caching

    Store sessions in Redis and cache HTTP responses with middleware.

    Try it Yourself »
    C#
    using Microsoft.Extensions.Caching.Distributed;
    using System.Text.Json;
    
    // Program.cs — Redis distributed cache
    builder.Services.AddStackExchangeRedisCache(options =>
    {
        options.Configuration = "localhost:6379";
        options.InstanceName = "MyApp_";
    });
    
    public class SessionService
    {
        private readonly IDistributedCache _cache;
    
        public SessionService(IDistributedCache cache)
        {
            _cache = cache;
        }
    
        // Store complex object in Redis
        public async Task SetUserSessionAsy
    ...

    Pro Tip

    Use cache stampede prevention: when a popular cache entry expires, hundreds of requests may hit the database simultaneously. Use SemaphoreSlim or a library like FusionCache to let only one request populate the cache while others wait.

    Common Mistakes

    • • Caching mutable objects — other code can modify the cached reference
    • • No cache invalidation — stale data persists after updates
    • • Using only sliding expiration — items that are always accessed never refresh

    Lesson Complete!

    You've mastered caching strategies in .NET. Next, build real-time features with SignalR.

    Sign up for free to track which lessons you've completed and get learning reminders.

    Previous

    Cookie & Privacy Settings

    We use cookies to improve your experience, analyze traffic, and show personalized ads. You can manage your preferences below.

    By clicking "Accept All", you consent to our use of cookies for analytics and personalized advertising. You can customize your preferences or reject non-essential cookies.

    Privacy PolicyTerms of Service