C#  

Redis in C# — A Technical Overview

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:

dotnet add package StackExchange.Redis

Connecting to Redis

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

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

Hash Operations

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

List Operations

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

Set Operations

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

Expiry

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

Working with Distributed Cache in .NET

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

Usage:

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

Pub/Sub Messaging

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

Distributed Lock with Redis

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

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.