Introduction

Redis is an open-source, in-memory data store known for delivering microsecond-level response times. In .NET applications, it is commonly used for caching, distributed locks, pub/sub messaging, and session management. The StackExchange.The Redis library is the standard client used in C# due to its performance and reliability.

Why Use Redis with C#

High throughput and low latency for microservices.
Efficient caching to reduce database load.
Supports key-value, lists, sets, hashes, sorted sets, and streams.
Distributed infrastructure support for cloud-native .NET applications.
Compatible with Azure Cache for Redis, AWS Elasticache, and on-prem instances.

Installing the Client

Use StackExchange.Redis package:

Code
dotnet add package StackExchange.Redis

Connecting to Redis

Code
using StackExchange.Redis;

var redis = ConnectionMultiplexer.Connect("localhost:6379");
IDatabase db = redis.GetDatabase();

The connection multiplexer is thread-safe and must be reused across the application.

Basic Operations

Set and Get

Code
db.StringSet("user:1", "Abhishek");
var value = db.StringGet("user:1");

Hash Operations

Code
db.HashSet("product:101", new HashEntry[]
{
    new HashEntry("name","Keyboard"),
    new HashEntry("price","1200")
});
var product = db.HashGetAll("product:101");

List Operations

Code
db.ListLeftPush("queue", "task1");
var task = db.ListRightPop("queue");

Set Operations

Code
db.SetAdd("tags", "dotnet");
bool exists = db.SetContains("tags", "dotnet");

Expiry

Code
db.StringSet("otp:9876", "1234", TimeSpan.FromMinutes(5));

Working with Distributed Cache in .NET

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

Usage:

Code
var cache = serviceProvider.GetRequiredService<IDistributedCache>();
await cache.SetStringAsync("key","value");
var str = await cache.GetStringAsync("key");

Pub/Sub Messaging

Code
var sub = redis.GetSubscriber();
await sub.PublishAsync("notifications", "Order Created");
await sub.SubscribeAsync("notifications",(channel, message) =>
{
    Console.WriteLine(message);
});

Distributed Lock with Redis

Code
string lockKey = "order-lock";
string lockValue = Guid.NewGuid().ToString();

bool acquired = db.StringSet(lockKey, lockValue, TimeSpan.FromSeconds(10), When.NotExists);

if(acquired)
{
    try
    {
        // critical section
    }
    finally
    {
        if(db.StringGet(lockKey) == lockValue)
            db.KeyDelete(lockKey);
    }
}

Using Redis for Caching Database Results

Code
string cacheKey = "users:list";

var cacheData = db.StringGet(cacheKey);

if(cacheData.IsNullOrEmpty)
{
    var users = await _dbContext.Users.ToListAsync();
    db.StringSet(cacheKey, JsonSerializer.Serialize(users), TimeSpan.FromMinutes(20));
}

Performance Considerations

Reuse the connection multiplexer instead of recreating.
Avoid large keys and values.
Use async methods for scaling.
Enable connection pooling when distributed across microservices.
Monitor Redis with INFO, MONITOR, Slowlog.

Common Use Cases

User session caching
API rate limiting
Microservice communication
Leaderboard systems with Sorted Sets
Background job queues
Token and OTP storage

Conclusion

Redis provides a high-performance architecture for modern .NET applications. Using StackExchange.Redis, developers can easily implement caching, distributed locks, messaging, and various data structures while enhancing speed and scalability.