home / skills / stuartf303 / sorcha / redis

redis skill

/.claude/skills/redis

This skill enables caching, token revocation, rate limiting, and distributed coordination with Redis to improve scalability and security.

npx playbooks add skill stuartf303/sorcha --skill redis

Review the files below or copy the command above to add this skill to your agents.

Files (3)
SKILL.md
3.7 KB
---
name: redis
description: |
  Implements Redis caching, session management, and distributed coordination for the Sorcha platform.
  Use when: Adding caching layers, token revocation, rate limiting, SignalR backplane, or distributed state.
allowed-tools: Read, Edit, Write, Glob, Grep, Bash, mcp__context7__resolve-library-id, mcp__context7__query-docs
---

# Redis Skill

Sorcha uses Redis via StackExchange.Redis for caching, token revocation tracking, rate limiting, and distributed coordination. All services share a single Redis instance managed by .NET Aspire with circuit breaker resilience.

## Quick Start

### Aspire Configuration

```csharp
// src/Apps/Sorcha.AppHost/AppHost.cs
var redis = builder.AddRedis("redis")
    .WithRedisCommander();

// Reference from any service
var blueprintService = builder.AddProject<Projects.Sorcha_Blueprint_Service>()
    .WithReference(redis);
```

### Cache Store Usage

```csharp
// Inject ICacheStore from Sorcha.Storage.Redis
public class MyService(ICacheStore cache)
{
    public async Task<User?> GetUserAsync(string id)
    {
        return await cache.GetAsync<User>($"user:{id}");
    }
    
    public async Task SetUserAsync(User user)
    {
        await cache.SetAsync($"user:{user.Id}", user, TimeSpan.FromMinutes(15));
    }
}
```

### Direct IConnectionMultiplexer

```csharp
// For operations beyond ICacheStore (Sets, rate limiting, etc.)
public class TokenService(IConnectionMultiplexer redis)
{
    private readonly IDatabase _db = redis.GetDatabase();
    
    public async Task TrackTokenAsync(string userId, string jti)
    {
        await _db.SetAddAsync($"auth:user_tokens:{userId}", jti);
    }
}
```

## Key Concepts

| Concept | Usage | Example |
|---------|-------|---------|
| Key prefix | Namespace isolation | `sorcha:`, `auth:` |
| TTL | Automatic expiration | `TimeSpan.FromMinutes(15)` |
| Circuit breaker | Graceful degradation | Breaks after 5 failures |
| Sets | Token tracking | `SetAddAsync`, `SetMembersAsync` |
| Counters | Rate limiting | `StringIncrementAsync` |

## Common Patterns

### Rate Limiting

**When:** Protecting auth endpoints from brute force.

```csharp
public async Task<bool> IsRateLimitedAsync(string identifier)
{
    var key = $"auth:failed:{identifier}";
    var count = await _db.StringIncrementAsync(key);
    
    if (count == 1)
        await _db.KeyExpireAsync(key, TimeSpan.FromSeconds(60));
    
    return count >= MaxFailedAttempts;
}
```

### Token Revocation

**When:** Invalidating JWTs before expiration.

```csharp
public async Task RevokeTokenAsync(string jti, DateTimeOffset expiresAt)
{
    var ttl = expiresAt - DateTimeOffset.UtcNow;
    if (ttl > TimeSpan.Zero)
        await _db.StringSetAsync($"auth:revoked:{jti}", "revoked", ttl);
}
```

## See Also

- [patterns](references/patterns.md) - Caching, resilience, key naming
- [workflows](references/workflows.md) - Setup, testing, debugging

## Related Skills

- **aspire** - Redis resource configuration and service discovery
- **jwt** - Token revocation integration
- **signalr** - Redis backplane for scale-out
- **docker** - Redis container configuration

## Documentation Resources

> Fetch latest Redis and StackExchange.Redis documentation with Context7.

**How to use Context7:**
1. Use `mcp__context7__resolve-library-id` to search for "StackExchange.Redis" or "redis"
2. Prefer website documentation (`/websites/redis_io`) for concepts
3. Use `/stackexchange/stackexchange.redis` for .NET-specific patterns

**Library IDs:**
- `/stackexchange/stackexchange.redis` - .NET client (344 snippets)
- `/websites/redis_io` - Redis concepts (29k+ snippets)

**Recommended Queries:**
- "Connection pooling multiplexer patterns best practices"
- "Caching patterns TTL expiration strategies"
- "Pub/Sub patterns distributed systems"

Overview

This skill implements Redis caching, session management, and distributed coordination for the Sorcha platform. It wires StackExchange.Redis through the Aspire configuration, exposes a high-level ICacheStore for common operations, and allows direct IConnectionMultiplexer access for advanced patterns. The integration focuses on resilience, namespace isolation, and practical patterns like rate limiting and token revocation.

How this skill works

The skill registers a single Redis instance via Aspire with circuit-breaker resilience and makes it available to all services. For everyday caching and TTLs you use ICacheStore; for sets, counters, pub/sub and other primitives you inject IConnectionMultiplexer and call IDatabase methods. Common patterns (rate limiting, token revocation, SignalR backplane) are implemented using keyed conventions and TTLs to avoid global state leaks.

When to use it

  • Add short-lived caching for read-heavy data (user profiles, lookups).
  • Implement token revocation and session invalidation for JWTs.
  • Enforce rate limiting and brute-force protection on auth endpoints.
  • Provide a SignalR backplane for scale-out across nodes.
  • Coordinate distributed tasks or leader election with Redis primitives.

Best practices

  • Use consistent key prefixes (e.g., sorcha:, auth:) to isolate namespaces.
  • Prefer ICacheStore for simple get/set TTL semantics and IConnectionMultiplexer for advanced primitives.
  • Apply TTLs to ephemeral keys to avoid unbounded memory growth.
  • Wrap Redis access with circuit-breaker or fallback logic to degrade gracefully.
  • Use Sets for token tracking and StringIncrement/StringExpire for counters to implement rate limits.

Example use cases

  • Cache user and lookup objects for 15 minutes using ICacheStore to reduce DB load.
  • Track active JWT IDs in a Set per user and check presence on each request for token revocation.
  • Implement per-identifier failed-attempt counters with StringIncrement and KeyExpire for login rate limiting.
  • Use Redis as a SignalR backplane to propagate messages between scaled instances.
  • Store short-lived distributed locks or coordination keys to manage background job ownership.

FAQ

Should I use ICacheStore or IConnectionMultiplexer?

Use ICacheStore for common caching and TTL-based patterns. Use IConnectionMultiplexer when you need Sets, counters, pub/sub, or atomic operations not exposed by the cache abstraction.

How do I avoid key collisions between services?

Adopt a strict key prefix convention (service or domain name like sorcha:auth:) and document prefixes for each service. TTLs help mitigate accidental long-lived collisions.