Install any skill in seconds. Free to start, no credit card required.
Get Started Free →Expert skill for distributed cache design, implementation, and optimization using Redis and Memcached. Design cache architectures, configure eviction policies, implement caching patterns (cache-aside, write-through, write-behind), monitor cache performance, and optimize memory usage.
.claude/skills/a5c-ai-distributed-caching/SKILL.md| Test case | Without → With | Effect | Δ tokens | Δ turns |
|---|---|---|---|---|
| case-01 | ✗→✓ | ▲ Improved | 146% | 0% |
| case-02 | ✗→✓ | ▲ Improved | 97% | 0% |
| case-07 | ✗→✓ | ▲ Improved | 157% | 0% |
| case-15 | ✗→✓ | ▲ Improved | 250% | 0% |
| case-12 | ✓→✗ | ▼ Worse | 148% | 0% |
You are distributed-caching - a specialized skill for distributed cache architecture and optimization. This skill provides expert capabilities for designing, implementing, and maintaining high-performance caching layers using Redis, Memcached, and related technologies.
This skill enables AI-powered caching operations including:
Design optimal data structures for use cases:
redis# String - Simple key-value caching SET user:1001:profile '{"name":"John","email":"john@example.com"}' EX 3600 GET user:1001:profile # Hash - Structured data with partial updates HSET product:5001 name "Widget" price 29.99 stock 150 HGET product:5001 price HINCRBY product:5001 stock -1 # Sorted Set - Leaderboards and ranking ZADD leaderboard 1500 "player:1" 2200 "player:2" 1800 "player:3" ZREVRANGE leaderboard 0 9 WITHSCORES # Top 10 ZRANK leaderboard "player:1" # List - Message queues and activity feeds LPUSH notifications:user:1001 '{"type":"order","id":"ord-123"}' LRANGE notifications:user:1001 0 19 # Latest 20 LTRIM notifications:user:1001 0 99 # Keep only 100 # Set - Tags, unique visitors, relationships SADD product:5001:tags "electronics" "sale" "featured" SINTER user:1001:interests product:5001:tags # Common interests # HyperLogLog - Cardinality estimation PFADD daily:visitors:20260124 "user:1001" "user:1002" "guest:abc" PFCOUNT daily:visitors:20260124 # Stream - Event sourcing and message streaming XADD orders * action "created" order_id "ord-123" total "99.99" XREAD COUNT 10 STREAMS orders 0 XGROUP CREATE orders order-processors $ MKSTREAM XREADGROUP GROUP order-processors worker-1 COUNT 10 STREAMS orders >
Implement common caching patterns:
pythonimport redis import json from functools import wraps r = redis.Redis(host='localhost', port=6379, decode_responses=True) # Cache-Aside Pattern (Lazy Loading) def get_user(user_id): cache_key = f"user:{user_id}" # Try cache first cached = r.get(cache_key) if cached: return json.loads(cached) # Cache miss - fetch from database user = database.get_user(user_id) # Populate cache with TTL r.setex(cache_key, 3600, json.dumps(user)) return user # Write-Through Pattern def update_user(user_id, data): cache_key = f"user:{user_id}" # Update database first database.update_user(user_id, data) # Update cache immediately r.setex(cache_key, 3600, json.dumps(data)) return data # Write-Behind (Write-Back) Pattern def update_user_async(user_id, data): cache_key = f"user:{user_id}" # Update cache immediately r.setex(cache_key, 3600, json.dumps(data)) # Queue database write r.lpush("write_queue", json.dumps({ "operation": "update_user", "user_id": user_id, "data": data, "timestamp": time.time() })) # Read-Through with Cache-Aside decorator def cached(ttl=3600, prefix="cache"): def decorator(func): @wraps(func) def wrapper(*args, **kwargs): # Generate cache key from function and arguments key = f"{prefix}:{func.__name__}:{hash(str(args) + str(kwargs))}" cached_value = r.get(key) if cached_value: return json.loads(cached_value) result = func(*args, **kwargs) r.setex(key, ttl, json.dumps(result)) return result return wrapper return decorator @cached(ttl=300, prefix="products") def get_product_recommendations(user_id, category): return recommendation_service.get_recommendations(user_id, category)
Implement robust cache invalidation:
python# Time-based invalidation (TTL) r.setex("session:abc123", 1800, session_data) # 30 minutes # Event-driven invalidation def on_user_updated(user_id): # Delete specific cache entries r.delete(f"user:{user_id}") r.delete(f"user:{user_id}:profile") # Delete pattern-matched keys (use with caution) keys = r.keys(f"user:{user_id}:*") if keys: r.delete(*keys) # Tag-based invalidation def set_with_tags(key, value, ttl, tags): pipe = r.pipeline() pipe.setex(key, ttl, value) for tag in tags: pipe.sadd(f"tag:{tag}", key) pipe.execute() def invalidate_by_tag(tag): keys = r.smembers(f"tag:{tag}") if keys: pipe = r.pipeline() pipe.delete(*keys) pipe.delete(f"tag:{tag}") pipe.execute() # Version-based invalidation def get_with_version(key, version_key): version = r.get(version_key) or "1" versioned_key = f"{key}:v{version}" return r.get(versioned_key) def invalidate_version(version_key): r.incr(version_key) # Increment version, old keys expire naturally
Configure Redis Cluster for scalability:
conf# redis-cluster.conf port 7000 cluster-enabled yes cluster-config-file nodes-7000.conf cluster-node-timeout 5000 appendonly yes appendfsync everysec # Memory management maxmemory 4gb maxmemory-policy allkeys-lru # Persistence save 900 1 save 300 10 save 60 10000 # Replication replica-read-only yes min-replicas-to-write 1 min-replicas-max-lag 10
bash# Create cluster redis-cli --cluster create \ 127.0.0.1:7000 127.0.0.1:7001 127.0.0.1:7002 \ 127.0.0.1:7003 127.0.0.1:7004 127.0.0.1:7005 \ --cluster-replicas 1 # Check cluster status redis-cli -c -p 7000 cluster info redis-cli -c -p 7000 cluster nodes # Rebalance slots redis-cli --cluster rebalance 127.0.0.1:7000
Configure Sentinel for automatic failover:
conf# sentinel.conf sentinel monitor mymaster 127.0.0.1 6379 2 sentinel auth-pass mymaster <password> sentinel down-after-milliseconds mymaster 5000 sentinel failover-timeout mymaster 60000 sentinel parallel-syncs mymaster 1 # Notification scripts sentinel notification-script mymaster /opt/redis/notify.sh sentinel client-reconfig-script mymaster /opt/redis/reconfig.sh
python# Python client with Sentinel from redis.sentinel import Sentinel sentinel = Sentinel([ ('sentinel1.example.com', 26379), ('sentinel2.example.com', 26379), ('sentinel3.example.com', 26379) ], socket_timeout=0.1) # Get master master = sentinel.master_for('mymaster', socket_timeout=0.1) master.set('key', 'value') # Get replica for reads replica = sentinel.slave_for('mymaster', socket_timeout=0.1) value = replica.get('key')
Configure optimal eviction policies:
conf# LRU - Least Recently Used (general purpose) maxmemory-policy allkeys-lru # LFU - Least Frequently Used (hot data scenarios) maxmemory-policy allkeys-lfu lfu-log-factor 10 lfu-decay-time 1 # Volatile - Only evict keys with TTL maxmemory-policy volatile-lru maxmemory-policy volatile-lfu maxmemory-policy volatile-ttl # No eviction - Return errors when full maxmemory-policy noeviction
Monitor cache health and performance:
bash# Redis INFO command redis-cli INFO stats redis-cli INFO memory redis-cli INFO replication redis-cli INFO clients # Key metrics to monitor # - hit_rate: keyspace_hits / (keyspace_hits + keyspace_misses) # - memory_usage: used_memory / maxmemory # - evicted_keys: Number of keys evicted # - connected_clients: Current client connections # - blocked_clients: Clients waiting on blocking operations
python# Calculate cache hit rate info = r.info('stats') hits = info['keyspace_hits'] misses = info['keyspace_misses'] hit_rate = hits / (hits + misses) * 100 if (hits + misses) > 0 else 0 print(f"Cache hit rate: {hit_rate:.2f}%") # Memory analysis memory_info = r.info('memory') print(f"Used memory: {memory_info['used_memory_human']}") print(f"Peak memory: {memory_info['used_memory_peak_human']}") print(f"Fragmentation ratio: {memory_info['mem_fragmentation_ratio']}")
This skill can leverage the following MCP servers:
| Server | Description | Installation | |--------|-------------|--------------| | mcp-redis (Official) | Redis data management | GitHub | | Redis Cloud Admin API | Cloud Redis management | See Redis documentation |
entity:id:attribute)This skill integrates with the following processes:
caching-strategy-design.js - Cache architecture planningWhen executing operations, provide structured output:
json{ "operation": "analyze-cache", "status": "success", "metrics": { "hitRate": 94.5, "missRate": 5.5, "evictionRate": 0.02, "memoryUsage": { "used": "3.2GB", "peak": "3.8GB", "maxmemory": "4GB", "utilizationPercent": 80 }, "connections": { "current": 45, "blocked": 0, "maxClients": 10000 } }, "recommendations": [ { "category": "memory", "issue": "High memory utilization", "action": "Consider increasing maxmemory or enabling LFU eviction", "priority": "medium" } ] }
| Error | Cause | Resolution | |-------|-------|------------| | OOM command not allowed | Memory limit reached | Increase maxmemory or enable eviction | | CLUSTERDOWN | Cluster not available | Check cluster health, majority nodes | | MOVED | Key on different node | Use cluster-aware client | | BUSY | Lua script running | Wait or kill script with SCRIPT KILL | | LOADING | Redis loading from disk | Wait for load to complete |
| Case | Status | Duration (ms) | Turns | Tokens | Tool calls | ||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Without | With | Δ | Without | With | Δ | Without | With | Δ | Without | With | Δ | ||
case-01 | fail→pass | 11,025 | 12,444 | +13% | 1 | 1 | 0% | 2,227 | 5,488 | +146% | 0 | 0 | — |
case-02 | fail→pass | 13,654 | 11,656 | -15% | 1 | 1 | 0% | 2,876 | 5,675 | +97% | 0 | 0 | — |
case-03 | pass→pass | 14,827 | 15,599 | +5% | 1 | 1 | 0% | 2,556 | 6,423 | +151% | 0 | 0 | — |
case-04 | pass→pass | 11,484 | 11,277 | -2% | 1 | 1 | 0% | 2,057 | 5,582 | +171% | 0 | 0 | — |
case-05 | fail→fail | 16,942 | 15,927 | -6% | 1 | 1 | 0% | 2,776 | 6,377 | +130% | 0 | 0 | — |
case-06 | pass→pass | 16,835 | 16,118 | -4% | 1 | 1 | 0% | 2,964 | 6,278 | +112% | 0 | 0 | — |
case-07 | fail→pass | 15,638 | 13,564 | -13% | 1 | 1 | 0% | 2,297 | 5,901 | +157% | 0 | 0 | — |
case-08 | pass→pass | 4,745 | 9,282 | +96% | 1 | 1 | 0% | 852 | 4,874 | +472% | 0 | 0 | — |
case-09 | fail→fail | 13,326 | 12,562 | -6% | 1 | 1 | 0% | 2,565 | 5,888 | +130% | 0 | 0 | — |
case-10 | pass→pass | 12,893 | 14,507 | +13% | 1 | 1 | 0% | 2,175 | 5,937 | +173% | 0 | 0 | — |
case-11 | pass→pass | 10,007 | 8,550 | -15% | 1 | 1 | 0% | 2,099 | 5,193 | +147% | 0 | 0 | — |
case-12 | pass→fail | 11,915 | 12,439 | +4% | 1 | 1 | 0% | 2,448 | 6,063 | +148% | 0 | 0 | — |
case-13 | pass→pass | 13,444 | 14,939 | +11% | 1 | 1 | 0% | 2,350 | 5,935 | +153% | 0 | 0 | — |
case-14 | pass→pass | 11,411 | 15,353 | +35% | 1 | 1 | 0% | 2,149 | 6,246 | +191% | 0 | 0 | — |
case-15 | fail→pass | 8,854 | 10,553 | +19% | 1 | 1 | 0% | 1,461 | 5,108 | +250% | 0 | 0 | — |
case-16 | pass→pass | 13,215 | 15,191 | +15% | 1 | 1 | 0% | 2,534 | 6,279 | +148% | 0 | 0 | — |
case-17 | pass→pass | 6,926 | 5,931 | -14% | 1 | 1 | 0% | 1,390 | 4,601 | +231% | 0 | 0 | — |
case-18 | pass→pass | 8,537 | 9,756 | +14% | 1 | 1 | 0% | 1,621 | 5,021 | +210% | 0 | 0 | — |
case-19 | pass→pass | 9,262 | 11,213 | +21% | 1 | 1 | 0% | 1,598 | 5,132 | +221% | 0 | 0 | — |
case-20 | pass→pass | 11,760 | 8,602 | -27% | 1 | 1 | 0% | 1,864 | 5,172 | +177% | 0 | 0 | — |
case-21 | pass→pass | 17,888 | 17,379 | -3% | 1 | 1 | 0% | 3,089 | 6,780 | +119% | 0 | 0 | — |
case-22 | pass→pass | 19,595 | 14,159 | -28% | 1 | 1 | 0% | 3,093 | 6,318 | +104% | 0 | 0 | — |
DecimalAI ran this skill against gemini-3.6-flash twice over the same eval suite — once with the skill loaded and once without — and compared the two runs case by case. 22 cases were attempted. The headline lift of +14 percentage points is the difference between those two pass rates over the 22 comparable cases. 1 case got worse with the skill loaded, and it is included in that figure.
Without the skill loaded, the model failed this case. With it loaded, the same prompt on the same model passed. This is one improved case from the latest verified run; every case, including any that regressed, is in the table above.
Other measured skills in the registry, with their headline benchmark lift.