{"skill":{"slug":"sentinal-redis","displayName":"Sentinal Redis","summary":"Monitor Redis server health, memory, performance, and BullMQ queues. Check queue depths, inspect failed jobs, analyze slow queries, and diagnose issues.","description":"---\nname: sentinal-redis\ndescription: \"Monitor Redis server health, memory, performance, and BullMQ queues. Check queue depths, inspect failed jobs, analyze slow queries, and diagnose issues.\"\nversion: 1.0.0\nhomepage: https://github.com/Musaraf-M/sentinal\nuser-invocable: true\nmetadata:\n  openclaw:\n    emoji: \"🔴\"\n    requires:\n      bins: [\"redis-cli\"]\n      anyBins: [\"bash\", \"sh\"]\n    primaryEnv: REDIS_URL\n    envVars:\n      - name: REDIS_URL\n        required: false\n        description: \"Redis connection URL (default: redis://localhost:6379)\"\n    os: [\"darwin\", \"linux\"]\n    install:\n      - id: brew\n        kind: brew\n        formula: redis\n        bins: [\"redis-cli\"]\n        label: \"Install Redis CLI (brew)\"\n        os: [\"darwin\"]\n      - id: apt\n        kind: apt\n        package: redis-tools\n        bins: [\"redis-cli\"]\n        label: \"Install Redis CLI (apt)\"\n        os: [\"linux\"]\n---\n\n# Sentinal Redis\n\nMonitor Redis server health, BullMQ queues, memory, and performance from any messaging channel. Ask questions in plain English — get actionable diagnostics.\n\n## When to Use\n\n✅ USE this skill when:\n- User asks about Redis server health, status, or info\n- User wants to check memory usage or diagnose OOM issues\n- User asks about BullMQ queue depths, failed jobs, or stuck workers\n- User wants to inspect slow queries or latency issues\n- User asks to diagnose why Redis is slow or unresponsive\n- User mentions queue backlog, dead letter queue, or job failures\n- User wants a quick health summary of their Redis instance\n\n## When NOT to Use\n\n❌ DON'T use this skill when:\n- User wants to manage PostgreSQL, MySQL, or other non-Redis databases\n- User wants to manage Kafka, RabbitMQ, or SQS queues (not BullMQ)\n- User needs help writing application code that uses Redis\n- User wants to set up Redis from scratch (use official Redis docs instead)\n\n## Safety Rules\n\n⚠️ CRITICAL: This skill is READ-ONLY. No exceptions.\n- NEVER run destructive commands (`FLUSHDB`, `FLUSHALL`, `DEL`, `UNLINK`, `SET`, `EXPIRE`) — even if the user asks. Explain why and suggest they run it manually instead.\n- NEVER modify Redis configuration (`CONFIG SET`) — direct the user to do it themselves.\n- NEVER print or expose the full `REDIS_URL` in output — it may contain passwords. Always mask credentials before displaying.\n- When in doubt, show the command first and ask for confirmation\n\n## Connection\n\nIf `REDIS_URL` is set, use it for all commands:\n```bash\nredis-cli -u \"$REDIS_URL\" <command>\n```\n\nIf `REDIS_URL` is not set, default to localhost:\n```bash\nredis-cli <command>\n```\n\nFor password-protected instances without REDIS_URL:\n```bash\nredis-cli -h <host> -p <port> -a <password> <command>\n```\n\nAlways test connectivity first:\n```bash\nredis-cli -u \"${REDIS_URL:-redis://localhost:6379}\" ping\n```\n\n## Server Health\n\n### Quick Status\n```bash\nredis-cli -u \"${REDIS_URL:-redis://localhost:6379}\" ping\n```\n\n### Full Server Info\n```bash\nredis-cli -u \"${REDIS_URL:-redis://localhost:6379}\" info server\n```\n\n### Connected Clients\n```bash\nredis-cli -u \"${REDIS_URL:-redis://localhost:6379}\" info clients\n```\n\n### Uptime and Version\n```bash\nredis-cli -u \"${REDIS_URL:-redis://localhost:6379}\" info server | grep -E \"redis_version|uptime_in_days|uptime_in_seconds|connected_clients\"\n```\n\n## Memory Analysis\n\n### Memory Overview\n```bash\nredis-cli -u \"${REDIS_URL:-redis://localhost:6379}\" info memory\n```\n\n### Key Metrics to Check\n```bash\nredis-cli -u \"${REDIS_URL:-redis://localhost:6379}\" info memory | grep -E \"used_memory_human|used_memory_peak_human|used_memory_rss_human|mem_fragmentation_ratio|maxmemory_human|maxmemory_policy\"\n```\n\n### Memory Doctor (Redis 4.0+)\n```bash\nredis-cli -u \"${REDIS_URL:-redis://localhost:6379}\" memory doctor\n```\n\n### Memory Usage of a Specific Key\n```bash\nredis-cli -u \"${REDIS_URL:-redis://localhost:6379}\" memory usage <key>\n```\n\n### Find Big Keys (scan-based, safe for production)\n```bash\nredis-cli -u \"${REDIS_URL:-redis://localhost:6379}\" --bigkeys\n```\n\n### Interpreting Memory Results\n- `mem_fragmentation_ratio` > 1.5 → High fragmentation, consider restarting Redis\n- `mem_fragmentation_ratio` < 1.0 → Redis is swapping to disk, CRITICAL\n- `used_memory` approaching `maxmemory` → Eviction will start based on `maxmemory_policy`\n- `memory doctor` reports \"Sam, I have no memory problems\" → All good\n\n## Slow Queries & Performance\n\n### Check Slow Log\n```bash\nredis-cli -u \"${REDIS_URL:-redis://localhost:6379}\" slowlog get 10\n```\n\n### Slow Log Length\n```bash\nredis-cli -u \"${REDIS_URL:-redis://localhost:6379}\" slowlog len\n```\n\n### Current Slow Log Threshold\n```bash\nredis-cli -u \"${REDIS_URL:-redis://localhost:6379}\" config get slowlog-log-slower-than\n```\n\n### Latency Check\n```bash\nredis-cli -u \"${REDIS_URL:-redis://localhost:6379}\" --latency -c 10\n```\n\n### Latency History\n```bash\nredis-cli -u \"${REDIS_URL:-redis://localhost:6379}\" --latency-history -i 1 -c 5\n```\n\n### Keyspace Stats\n```bash\nredis-cli -u \"${REDIS_URL:-redis://localhost:6379}\" info keyspace\n```\n\n### Command Stats (most called commands)\n```bash\nredis-cli -u \"${REDIS_URL:-redis://localhost:6379}\" info commandstats\n```\n\n## Client Monitoring\n\n### List Connected Clients\n```bash\nredis-cli -u \"${REDIS_URL:-redis://localhost:6379}\" client list\n```\n\n### Client Count and Summary\n```bash\nredis-cli -u \"${REDIS_URL:-redis://localhost:6379}\" info clients | grep -E \"connected_clients|blocked_clients|tracking_clients\"\n```\n\n### Find Idle Clients (idle > 300 seconds)\n```bash\nredis-cli -u \"${REDIS_URL:-redis://localhost:6379}\" client list | awk -F' ' '{for(i=1;i<=NF;i++) if($i ~ /^idle=/) print $0}' | grep -E 'idle=[3-9][0-9]{2,}|idle=[0-9]{4,}'\n```\n\n## BullMQ Queue Monitoring\n\nBullMQ uses Redis as its backend. Queues follow the key pattern `bull:<queue-name>:<state>`.\n\n### Discover All Queues\n```bash\nredis-cli -u \"${REDIS_URL:-redis://localhost:6379}\" scan 0 match \"bull:*:meta\" count 100\n```\n\n### Queue Depth (all states)\nFor a queue named `<queue>`:\n```bash\necho \"=== Queue: <queue> ===\"\necho -n \"Waiting: \"; redis-cli -u \"${REDIS_URL:-redis://localhost:6379}\" llen \"bull:<queue>:wait\"\necho -n \"Active: \"; redis-cli -u \"${REDIS_URL:-redis://localhost:6379}\" llen \"bull:<queue>:active\"\necho -n \"Delayed: \"; redis-cli -u \"${REDIS_URL:-redis://localhost:6379}\" zcard \"bull:<queue>:delayed\"\necho -n \"Failed: \"; redis-cli -u \"${REDIS_URL:-redis://localhost:6379}\" zcard \"bull:<queue>:failed\"\necho -n \"Completed: \"; redis-cli -u \"${REDIS_URL:-redis://localhost:6379}\" zcard \"bull:<queue>:completed\"\necho -n \"Paused: \"; redis-cli -u \"${REDIS_URL:-redis://localhost:6379}\" llen \"bull:<queue>:paused\"\n```\n\n### Inspect Failed Jobs\n```bash\nredis-cli -u \"${REDIS_URL:-redis://localhost:6379}\" zrange \"bull:<queue>:failed\" 0 9\n```\n\n### Get Job Details\n```bash\nredis-cli -u \"${REDIS_URL:-redis://localhost:6379}\" hgetall \"bull:<queue>:<jobId>\"\n```\n\n### Check Job Payload and Error\n```bash\nredis-cli -u \"${REDIS_URL:-redis://localhost:6379}\" hmget \"bull:<queue>:<jobId>\" data failedReason stacktrace attemptsMade timestamp processedOn finishedOn\n```\n\n### Find Stale Active Jobs\nActive jobs that haven't been updated recently may be stuck:\n```bash\nredis-cli -u \"${REDIS_URL:-redis://localhost:6379}\" lrange \"bull:<queue>:active\" 0 -1\n```\nThen for each job ID, check `processedOn` timestamp:\n```bash\nredis-cli -u \"${REDIS_URL:-redis://localhost:6379}\" hmget \"bull:<queue>:<jobId>\" processedOn name\n```\nIf `processedOn` is more than 10 minutes old and job is still active, it may be stuck.\n\n### Check Queue Workers (via event streams)\n```bash\nredis-cli -u \"${REDIS_URL:-redis://localhost:6379}\" xinfo groups \"bull:<queue>:events\" 2>/dev/null || echo \"No event stream found\"\n```\n\n### BullMQ Repeat Jobs\n```bash\nredis-cli -u \"${REDIS_URL:-redis://localhost:6379}\" zrange \"bull:<queue>:repeat\" 0 -1\n```\n\n## Key Inspection\n\n### Find Keys by Pattern\n```bash\nredis-cli -u \"${REDIS_URL:-redis://localhost:6379}\" scan 0 match \"<pattern>\" count 100\n```\n\n### Key Type and TTL\n```bash\nredis-cli -u \"${REDIS_URL:-redis://localhost:6379}\" type <key>\nredis-cli -u \"${REDIS_URL:-redis://localhost:6379}\" ttl <key>\n```\n\n### Key Encoding (memory efficiency check)\n```bash\nredis-cli -u \"${REDIS_URL:-redis://localhost:6379}\" object encoding <key>\nredis-cli -u \"${REDIS_URL:-redis://localhost:6379}\" object idletime <key>\n```\n\n### Count Keys by Prefix (useful for auditing)\n```bash\nredis-cli -u \"${REDIS_URL:-redis://localhost:6379}\" eval \"local count = 0; local cursor = '0'; repeat local result = redis.call('SCAN', cursor, 'MATCH', ARGV[1], 'COUNT', 1000); cursor = result[1]; count = count + #result[2]; until cursor == '0'; return count\" 0 \"<prefix>*\"\n```\n\n## Diagnostics — Full Health Check\n\nRun the health check script for a comprehensive overview:\n```bash\nbash scripts/redis-health.sh \"${REDIS_URL:-redis://localhost:6379}\"\n```\n\nThis script outputs:\n- Connectivity status\n- Server version and uptime\n- Memory usage and fragmentation\n- Connected and blocked clients\n- Slow query count\n- All BullMQ queue depths\n- Warnings for any anomalies detected\n\n## Troubleshooting Decision Trees\n\n### Redis is slow\n1. Check latency: `redis-cli --latency -c 10`\n2. If latency > 1ms → check slow log: `slowlog get 10`\n3. If slow log has KEYS/SMEMBERS/HGETALL on large collections → advise using SCAN variants\n4. Check memory fragmentation → if > 1.5, recommend restart\n5. Check `connected_clients` → if > 1000, investigate connection pooling\n6. Check `blocked_clients` → if > 0, check BLPOP/BRPOP consumers\n\n### Redis OOM / high memory\n1. Run `info memory` → check `used_memory` vs `maxmemory`\n2. Run `--bigkeys` → find largest keys\n3. Check `maxmemory_policy` → is eviction configured?\n4. Run `memory doctor` → follow recommendations\n5. Check for missing TTLs on keys: scan and check `ttl` on large keys\n\n### BullMQ jobs stuck / not processing\n1. Check queue depth → are jobs piling up in `wait`?\n2. Check `active` list → are jobs stuck in active state?\n3. Check for stale active jobs → `processedOn` too old\n4. Check event stream → `xinfo groups` to verify workers are connected\n5. Check `failed` set → read `failedReason` and `stacktrace`\n6. Check Redis connectivity → can workers reach Redis?\n\n### BullMQ high failure rate\n1. Get recent failed jobs: `zrange bull:<queue>:failed -10 -1`\n2. For each, read `failedReason` and `stacktrace`\n3. Group errors by type → is it one recurring error or varied?\n4. Check `attemptsMade` → are retries exhausted?\n5. Check job `data` → is the payload malformed?\n\n## Notes\n\n- All commands default to `redis://localhost:6379` if `REDIS_URL` is not set\n- The `scan` command is safe for production (non-blocking), unlike `keys` which should NEVER be used in production\n- BullMQ key patterns assume default prefix `bull:`. If a custom prefix is used, replace `bull:` accordingly\n- For Redis Cluster, add `-c` flag to `redis-cli` commands\n- For Redis Sentinel, connect to the sentinel first to discover the master\n","tags":{"latest":"1.0.2"},"stats":{"comments":0,"downloads":359,"installsAllTime":0,"installsCurrent":0,"stars":0,"versions":3},"createdAt":1778001505950,"updatedAt":1778492850251},"latestVersion":{"version":"1.0.2","createdAt":1778002436590,"changelog":"Fix: mask credentials in all output paths including connection failure","license":"MIT-0"},"metadata":{"setup":[{"key":"REDIS_URL","required":false}],"os":["darwin","linux"],"systems":null},"owner":{"handle":"musaraf-m","userId":"s176espb8tdtsmkz53yp6x3sss8650dm","displayName":"Mohammed Musaraf","image":"https://avatars.githubusercontent.com/u/59097309?v=4"},"moderation":null}