home / skills / doanchienthangdev / omgkit / redis

redis skill

/plugin/skills/databases/redis

This skill helps you implement Redis caching, session storage, rate limiting, pub/sub, and streams for scalable data patterns in JavaScript.

npx playbooks add skill doanchienthangdev/omgkit --skill redis

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

Files (1)
SKILL.md
3.2 KB
---
name: Developing with Redis
description: The agent implements Redis caching, data structures, and real-time messaging patterns. Use when implementing caching layers, session storage, rate limiting, pub/sub messaging, or distributed data structures.
---

# Developing with Redis

## Quick Start

```typescript
import Redis from 'ioredis';

const redis = new Redis({
  host: process.env.REDIS_HOST || 'localhost',
  port: parseInt(process.env.REDIS_PORT || '6379'),
  maxRetriesPerRequest: 3,
});

// Basic caching
await redis.setex('user:123', 3600, JSON.stringify(userData));
const cached = await redis.get('user:123');
```

## Features

| Feature | Description | Guide |
|---------|-------------|-------|
| Caching | High-speed key-value storage with TTL | Use `setex` for auto-expiration, `get` for retrieval |
| Session Storage | Distributed session management | Store sessions with user ID index for multi-device |
| Rate Limiting | Request throttling with sliding windows | Use sorted sets or token bucket algorithms |
| Pub/Sub | Real-time messaging between services | Separate subscriber connections from publishers |
| Streams | Event sourcing and message queues | Consumer groups for reliable message processing |
| Data Structures | Lists, sets, sorted sets, hashes | Choose structure based on access patterns |

## Common Patterns

### Cache-Aside Pattern

```typescript
async function getOrSet<T>(key: string, factory: () => Promise<T>, ttl = 3600): Promise<T> {
  const cached = await redis.get(key);
  if (cached) return JSON.parse(cached);

  const value = await factory();
  await redis.setex(key, ttl, JSON.stringify(value));
  return value;
}
```

### Sliding Window Rate Limiter

```typescript
async function checkRateLimit(key: string, limit: number, windowSec: number): Promise<boolean> {
  const now = Date.now();
  const windowStart = now - windowSec * 1000;

  const pipeline = redis.pipeline();
  pipeline.zremrangebyscore(key, '-inf', windowStart);
  pipeline.zadd(key, now, `${now}:${Math.random()}`);
  pipeline.zcard(key);
  pipeline.expire(key, windowSec);

  const results = await pipeline.exec();
  const count = results?.[2]?.[1] as number;
  return count <= limit;
}
```

### Distributed Lock

```typescript
async function acquireLock(key: string, ttlMs = 10000): Promise<string | null> {
  const lockId = crypto.randomUUID();
  const acquired = await redis.set(`lock:${key}`, lockId, 'PX', ttlMs, 'NX');
  return acquired === 'OK' ? lockId : null;
}

async function releaseLock(key: string, lockId: string): Promise<boolean> {
  const script = `if redis.call("get",KEYS[1])==ARGV[1] then return redis.call("del",KEYS[1]) else return 0 end`;
  return (await redis.eval(script, 1, `lock:${key}`, lockId)) === 1;
}
```

## Best Practices

| Do | Avoid |
|----|-------|
| Set TTL on all cache keys | Storing objects larger than 100KB |
| Use pipelines for batch operations | Using `KEYS` command in production |
| Implement connection pooling | Ignoring memory limits and eviction |
| Use Lua scripts for atomic operations | Using Redis as primary database |
| Add key prefixes for namespacing | Blocking on long-running operations |
| Monitor memory with `INFO memory` | Storing sensitive data unencrypted |
| Set up Redis Sentinel for HA | Skipping connection error handling |

Overview

This skill implements practical patterns for developing with Redis in JavaScript. It covers caching, session storage, rate limiting, pub/sub, streams, distributed locks, and common data structures. The content focuses on code-first recipes and production-ready configurations for reliability and performance.

How this skill works

The skill provides sample code and helper functions that interact with Redis via ioredis, showing connection setup, TTL-based caching, pipelined operations, Lua scripts for atomicity, and pub/sub/stream patterns. It inspects access patterns and recommends data structures (hashes, lists, sets, sorted sets) and operational controls like TTLs, connection retries, and memory monitoring. The guidance balances developer ergonomics with safety: namespacing, avoiding heavy commands, and using Sentinel for HA.

When to use it

  • Add a fast caching layer to reduce database load and improve read latency.
  • Store distributed session state for multi-device user sessions.
  • Implement per-user or per-endpoint rate limiting with sliding windows.
  • Implement real-time messaging between services using pub/sub or streams.
  • Coordinate distributed processes using locks or consumer groups for reliable processing.

Best practices

  • Always set TTLs on cache keys and use key prefixes for clear namespacing.
  • Use pipelines for batching and Lua scripts for multi-step atomic operations.
  • Avoid KEYS in production; prefer indexed patterns or SCAN for large datasets.
  • Monitor memory and eviction policies; keep individual values well under 100KB.
  • Handle connection errors and configure retries, timeouts, and pooling.
  • Use Redis Sentinel or cluster mode for high availability and failover.

Example use cases

  • Cache user profiles with setex and a cache-aside getOrSet helper.
  • Enforce API quotas using a sliding-window limiter built on sorted sets.
  • Build a job queue with streams and consumer groups for reliable processing.
  • Send system notifications with pub/sub while keeping separate client connections for subscribers.
  • Protect critical sections across services using a short-lived distributed lock.

FAQ

Can I use Redis as the primary database?

No. Redis is excellent as a fast store and cache, but not recommended as the primary durable database for large or complex datasets.

How large should cached objects be?

Keep cached objects small (preferably <100KB). Large objects increase memory pressure and eviction risk.