Implement Redis Cache in ASP.NET Core API


Caching is one of the most effective ways to improve application performance and scalability. When building high-performance APIs in ASP.NET Core, integrating Redis Cache can significantly reduce database load and response time.

What is Redis?

Redis (Remote Dictionary Server) is an open-source, in-memory data store used as a database, cache, and message broker. It stores data in RAM, making it extremely fast compared to traditional databases.

Why Use Redis Cache?

  • Ultra-fast data access (in-memory)
  • Reduces database load
  • Improves API response time
  • Supports distributed caching
  • Scalable and highly available

Prerequisites

Before we start, make sure you have:

  • .NET 6 / .NET 7 / .NET 8 installed
  • ASP.NET Core Web API project
  • Redis installed locally or using Docker

Step 1: Install Redis

Option 1: Using Docker

docker run -d -p 6379:6379 redis

Option 2: Install locally

Download from official Redis site or use WSL for Windows.

Step 2: Install Required NuGet Package

Install Redis caching package:

dotnet add package Microsoft.Extensions.Caching.StackExchangeRedis

Step 3: Configure Redis in appsettings.json

"RedisCacheSettings": {
  "ConnectionString": "localhost:6379",
  "InstanceName": "MyApp_"
}

Step 4: Register Redis in Program.cs

builder.Services.AddStackExchangeRedisCache(options =>
{
    options.Configuration = builder.Configuration["RedisCacheSettings:ConnectionString"];
    options.InstanceName = builder.Configuration["RedisCacheSettings:InstanceName"];
});

Step 5: Create a Cache Service

To keep things clean and reusable, create a service:

public interface ICacheService
{
    Task<T> GetAsync<T>(string key);
    Task SetAsync<T>(string key, T value, TimeSpan? expiry = null);
    Task RemoveAsync(string key);
}

Implementation

using Microsoft.Extensions.Caching.Distributed;
using System.Text.Json;

public class CacheService : ICacheService
{
    private readonly IDistributedCache _cache;

    public CacheService(IDistributedCache cache)
    {
        _cache = cache;
    }

    public async Task<T> GetAsync<T>(string key)
    {
        var data = await _cache.GetStringAsync(key);
        if (data == null) return default;

        return JsonSerializer.Deserialize<T>(data);
    }

    public async Task SetAsync<T>(string key, T value, TimeSpan? expiry = null)
    {
        var options = new DistributedCacheEntryOptions
        {
            AbsoluteExpirationRelativeToNow = expiry ?? TimeSpan.FromMinutes(5)
        };

        var jsonData = JsonSerializer.Serialize(value);
        await _cache.SetStringAsync(key, jsonData, options);
    }

    public async Task RemoveAsync(string key)
    {
        await _cache.RemoveAsync(key);
    }
}

Step 6: Register Cache Service

builder.Services.AddScoped<ICacheService, CacheService>();

Step 7: Use Redis Cache in Controller

[ApiController]
[Route("api/[controller]")]
public class ProductsController : ControllerBase
{
    private readonly ICacheService _cacheService;

    public ProductsController(ICacheService cacheService)
    {
        _cacheService = cacheService;
    }

    [HttpGet]
    public async Task<IActionResult> GetProducts()
    {
        string cacheKey = "product_list";

        var cachedData = await _cacheService.GetAsync<List<string>>(cacheKey);

        if (cachedData != null)
        {
            return Ok(new
            {
                Source = "Cache",
                Data = cachedData
            });
        }

        // Simulate DB call
        var products = new List<string> { "Laptop", "Mobile", "Tablet" };

        await _cacheService.SetAsync(cacheKey, products, TimeSpan.FromMinutes(10));

        return Ok(new
        {
            Source = "Database",
            Data = products
        });
    }
}

Step 8: Test the API

  • First request → Data comes from Database
  • Second request → Data comes from Redis Cache

Cache Expiration Strategies

  • Absolute Expiration → Fixed time (e.g., 10 minutes)
  • Sliding Expiration → Reset expiry on access
  • No Expiry → Persistent (use carefully)

Example:

options.SlidingExpiration = TimeSpan.FromMinutes(5);

Best Practices

  • Use meaningful cache keys (user_123_profile)
  • Avoid caching sensitive data
  • Set appropriate expiration times
  • Use compression for large data
  • Monitor cache performance

When NOT to Use Redis

  • Frequently changing data
  • Small applications with low traffic
  • When data consistency is critical without invalidation logic

Advanced Use Cases

  • Distributed session storage
  • API rate limiting
  • Background job queues
  • Real-time analytics

Conclusion

Integrating Redis with ASP.NET Core API is straightforward and highly beneficial for performance optimization. It helps reduce database calls, improves scalability, and enhances user experience.

0 Comments Report