DEV Community

Vigilmon
Vigilmon

Posted on

How to Monitor Your Redis Cache with Vigilmon

How to Monitor Your Redis Cache with Vigilmon

Redis is one of those services that teams often treat as "just a cache" — until it goes down and takes the entire application with it. When Redis is used for sessions, job queues, rate limiting, or real-time pub/sub, its availability is as critical as your primary database.

This guide shows you how to monitor Redis properly using Vigilmon.

Why Redis Monitoring Is Critical

Redis failures manifest in unexpected ways:

  • Session store failure: Users are logged out instantly, support tickets flood in
  • Job queue backup: Background jobs stop processing silently
  • Rate limiter collapse: Either all requests get through or all get blocked
  • Cache stampede: Redis restart causes every request to hit your database simultaneously
  • Memory limit reached: Redis starts evicting keys, breaking features that depend on them
  • Replication failure: Writes on primary not reaching replicas

Creating a Redis Health Check Endpoint

Node.js with ioredis

const Redis = require('ioredis');
const redis = new Redis(process.env.REDIS_URL);

app.get('/health/redis', async (req, res) => {
  try {
    const start = Date.now();

    // PING/PONG check
    const pong = await redis.ping();
    if (pong !== 'PONG') throw new Error('Unexpected Redis response');

    const latency = Date.now() - start;

    // Get memory info
    const info = await redis.info('memory');
    const usedMemory = info.match(/used_memory_human:(S+)/)?.[1];
    const maxMemory = info.match(/maxmemory_human:(S+)/)?.[1];

    res.json({
      status: 'ok',
      latency_ms: latency,
      memory: { used: usedMemory, max: maxMemory }
    });
  } catch (err) {
    res.status(503).json({ status: 'error', message: err.message });
  }
});
Enter fullscreen mode Exit fullscreen mode

Python with redis-py

import redis
import time
from flask import Flask, jsonify

app = Flask(__name__)
r = redis.Redis.from_url(os.getenv('REDIS_URL'), decode_responses=True)

@app.route('/health/redis')
def redis_health():
    try:
        start = time.time()
        r.ping()
        latency_ms = (time.time() - start) * 1000

        # Check memory usage
        info = r.info('memory')
        used_memory = info['used_memory_human']

        return jsonify({
            'status': 'ok',
            'latency_ms': round(latency_ms, 2),
            'memory_used': used_memory
        })
    except redis.ConnectionError as e:
        return jsonify({'status': 'error', 'message': str(e)}), 503
Enter fullscreen mode Exit fullscreen mode

Ruby on Rails

# config/routes.rb
get '/health/redis', to: 'health#redis'

# app/controllers/health_controller.rb
def redis
  start = Time.now
  Redis.current.ping
  latency_ms = ((Time.now - start) * 1000).round(2)

  render json: { status: 'ok', latency_ms: latency_ms }
rescue Redis::CannotConnectError => e
  render json: { status: 'error', message: e.message }, status: 503
end
Enter fullscreen mode Exit fullscreen mode

Monitoring Redis Memory

Memory pressure is the most common Redis issue. Add memory monitoring to your health check:

app.get('/health/redis/memory', async (req, res) => {
  const info = await redis.info('memory');
  const usedBytes = parseInt(info.match(/used_memory:(d+)/)?.[1] || 0);
  const maxBytes = parseInt(info.match(/maxmemory:(d+)/)?.[1] || 0);

  if (maxBytes > 0) {
    const usagePercent = (usedBytes / maxBytes) * 100;

    if (usagePercent > 90) {
      return res.status(503).json({
        status: 'critical',
        usage_percent: usagePercent.toFixed(1),
        message: 'Redis memory above 90% — eviction imminent'
      });
    }

    if (usagePercent > 75) {
      return res.status(200).json({
        status: 'warning',
        usage_percent: usagePercent.toFixed(1)
      });
    }
  }

  res.json({ status: 'ok', usage_percent: maxBytes > 0 ? ((usedBytes/maxBytes)*100).toFixed(1) : 'unlimited' });
});
Enter fullscreen mode Exit fullscreen mode

Monitoring Redis Cluster

For Redis Cluster setups, monitor the cluster health:

app.get('/health/redis/cluster', async (req, res) => {
  try {
    const info = await redis.cluster('INFO');
    const clusterState = info.match(/cluster_state:(w+)/)?.[1];
    const clusterSize = info.match(/cluster_size:(d+)/)?.[1];

    if (clusterState !== 'ok') {
      return res.status(503).json({
        status: 'error',
        cluster_state: clusterState,
        cluster_size: clusterSize
      });
    }

    res.json({ status: 'ok', cluster_state: clusterState, nodes: clusterSize });
  } catch (err) {
    res.status(503).json({ status: 'error', message: err.message });
  }
});
Enter fullscreen mode Exit fullscreen mode

Setting Up Vigilmon

  1. Go to vigilmon.online and create a free account
  2. Add MonitorHTTP(S)
  3. URL: https://yourapp.com/health/redis
  4. Interval: 1 minute (Redis failures are fast and impact is immediate)
  5. Response check: status code 200, body contains "status":"ok"
  6. Response time alert: warn if over 500ms (Redis should respond in <10ms normally)

Recommended Alert Thresholds

Check Warning Critical
Connectivity Any failure Any failure
Response time >100ms >500ms
Memory usage >75% >90%
Connected clients >1000 >5000
Replication lag >5s >30s

The Cache Stampede Prevention

When Redis restarts, a common disaster is the "cache stampede" — all requests simultaneously hit your database. Vigilmon alerts you the moment Redis goes down, giving you time to take action:

  1. Enable circuit breakers in your app to limit DB fallback traffic
  2. Warm the cache from a snapshot before re-enabling traffic
  3. Use Vigilmon's status page to communicate to your team during the incident

Summary

Redis monitoring should be as rigorous as database monitoring. With Vigilmon, you get:

  • Sub-minute alerting when Redis becomes unavailable
  • Response time tracking to catch slow Redis before it cascades
  • Memory monitoring to prevent surprise evictions
  • Cluster health visibility for distributed Redis deployments

Set up Redis monitoring for free at vigilmon.online.

Top comments (0)