
Redis Patterns
Apply Redis caching, rate limits, locks, sessions, and pub/sub with production-safe patterns while implementing backend features.
Overview
Redis-patterns is an agent skill for the Build phase that documents Redis data structures, caching, coordination, and production connection patterns.
Install
npx skills add https://github.com/affaan-m/everything-claude-code --skill redis-patternsWhat is this skill?
- Data structure cheat sheet mapping use cases to strings, hashes, sorted sets, sets, lists, and streams
- When to activate: caching, rate limiting, distributed locks, session storage, pub/sub, and prod tuning
- Clarifies atomicity: single commands vs Lua, MULTI/EXEC, or explicit sync for multi-step workflows
- Covers RDB/AOF persistence, RESP, and connection pooling to avoid per-request handshake overhead
- Production-oriented topics: eviction, clustering, and throttling patterns
- Data structure cheat sheet table covering strings, hashes, sorted sets, sets, lists, and streams
Adoption & trust: 1.2k installs on skills.sh; 210k GitHub stars; 3/3 security scanners passed (skills.sh audits).
What problem does it solve?
You are adding Redis for cache or limits but are unsure which structure to use and how to keep multi-step updates correct under concurrency.
Who is it for?
Indie backend devs adding Redis to Node or similar stacks for cache, sessions, leaderboards, or throttling on a single instance or small cluster.
Skip if: Greenfield apps with no latency or coordination needs where a plain SQL or serverless cache is simpler and cheaper.
When should I use this skill?
Adding caching, rate limiting, distributed locks, session/token storage, pub/sub or streams, or production Redis pooling and eviction.
What do I get? / Deliverables
Your agent proposes structure-specific keys, atomic patterns, and pooling/persistence choices aligned to caching, sessions, messaging, or rate limits.
- Key naming and structure recommendations
- Atomic workflow pattern (Lua/MULTI) for multi-step updates
- Caching or throttling implementation outline
Recommended Skills
Journey fit
Redis patterns sit in Build because they are implemented when wiring persistence, caching, and coordination into a running app. Backend is the canonical shelf: strings, hashes, streams, pooling, and atomic multi-step workflows are server-side concerns.
How it compares
Reference skill for Redis design choices—not a replacement for your ORM, queue product, or cloud Redis console.
Common Questions / FAQ
Who is redis-patterns for?
Solo builders and small teams implementing backend features that need in-memory caching, coordination, or messaging with Redis.
When should I use redis-patterns?
During Build/backend work when adding caching, rate limiting, distributed locks, session storage, pub/sub or streams, or tuning pools and eviction before ship.
Is redis-patterns safe to install?
It is guidance-only; applying patterns still requires your own Redis credentials and network access—check the Security Audits panel on this page.
SKILL.md
READMESKILL.md - Redis Patterns
# Redis Patterns Quick reference for Redis best practices across common backend use cases. ## How It Works Redis is an in-memory data structure store that supports strings, hashes, lists, sets, sorted sets, streams, and more. Individual Redis commands are atomic on a single instance; multi-step workflows require Lua scripts, MULTI/EXEC transactions, or explicit synchronization to stay atomic. Data is optionally persisted via RDB snapshots or AOF logs. Clients communicate over TCP using the RESP protocol; connection pools are essential to avoid per-request handshake overhead. ## When to Activate - Adding caching to an application - Implementing rate limiting or throttling - Building distributed locks or coordination - Setting up session or token storage - Using Pub/Sub or Redis Streams for messaging - Configuring Redis in production (pooling, eviction, clustering) ## Data Structure Cheat Sheet | Use Case | Structure | Example Key | |----------|-----------|-------------| | Simple cache | String | `product:123` | | User session | Hash | `session:abc` | | Leaderboard | Sorted Set | `scores:weekly` | | Unique visitors | Set | `visitors:2024-01-01` | | Activity feed | List | `feed:user:456` | | Event stream | Stream | `events:orders` | | Counters / rate limits | String (INCR) | `ratelimit:user:123` | | Bloom filter / HLL | HyperLogLog | `hll:pageviews` | ## Core Patterns ### Cache-Aside (Lazy Loading) ```python import redis import json r = redis.Redis(host='localhost', port=6379, decode_responses=True) def get_product(product_id: int): cache_key = f"product:{product_id}" cached = r.get(cache_key) if cached: return json.loads(cached) product = db.query("SELECT * FROM products WHERE id = %s", product_id) r.setex(cache_key, 3600, json.dumps(product)) # TTL: 1 hour return product ``` ### Write-Through Cache ```python def update_product(product_id: int, data: dict): # Write to DB first db.execute("UPDATE products SET ... WHERE id = %s", product_id) # Immediately update cache cache_key = f"product:{product_id}" r.setex(cache_key, 3600, json.dumps(data)) ``` ### Cache Invalidation ```python # Tag-based invalidation — group related keys under a set def cache_product(product_id: int, category_id: int, data: dict): key = f"product:{product_id}" tag = f"tag:category:{category_id}" pipe = r.pipeline(transaction=True) pipe.setex(key, 3600, json.dumps(data)) pipe.sadd(tag, key) pipe.expire(tag, 3600) pipe.execute() def invalidate_category(category_id: int): tag = f"tag:category:{category_id}" keys = r.smembers(tag) if keys: r.delete(*keys) r.delete(tag) ``` ### Session Storage ```python import time import uuid def create_session(user_id: int, ttl: int = 86400) -> str: session_id = str(uuid.uuid4()) key = f"session:{session_id}" pipe = r.pipeline(transaction=True) pipe.hset(key, mapping={ "user_id": user_id, "created_at": int(time.time()), }) pipe.expire(key, ttl) pipe.execute() return session_id def get_session(session_id: str) -> dict | None: data = r.hgetall(f"session:{session_id}") return data if data else None def delete_session(session_id: str): r.delete(f"session:{session_id}") ``` ## Rate Limiting ### Fixed Window (Simple) ```python def is_rate_limited(user_id: int, limit: int = 100, window: int = 60) -> bool: key = f"ratelimit:{user_id}:{int(time.time()) // window}" pipe = r.pipeline(transaction=True) pipe.incr(key) pipe.expire(key, window) count, _ = pipe.execute() return count > limit ``` ### Sliding Window (Lua — Atomic) ```lua -- sliding_window.lua local key = KEYS[1] local now = tonumber(ARGV[1]) local window = tonumbe