Uptime Monitoring for Redis Cloud Applications (Free, Multi-Region)
Redis Cloud (managed Redis from Redis Ltd.) gives you a reliable, low-latency key-value store without running your own Redis cluster. But "managed" means Redis manages the server — not your connection layer, your eviction policy, or the way your application uses it.
Here's how to add health checks and external monitoring to a Redis Cloud-backed application.
The failure modes that bite Redis Cloud users
Connection exhaustion — Each Redis Cloud subscription has a maximum connection count. Serverless functions that create a new client per invocation, forget to close connections, or don't reuse a shared client will exhaust the limit. New connections start failing silently.
Eviction under memory pressure — Redis Cloud databases have a maximum memory setting. When memory is full, the eviction policy kicks in (usually allkeys-lru or volatile-lru). If your application expects keys to always be present, silent evictions turn into cache misses that hit your database — or worse, crash your app if you're using Redis as a session store.
TLS certificate issues — Redis Cloud requires TLS in production. If your certificate bundle expires or the CA isn't trusted by your client, connections fail. This is more common than you'd expect after OS upgrades or container image rebuilds.
Network changes — Firewall rules, VPC peering, or security group changes between your app and Redis Cloud can silently block connections.
Step 1: Add a Redis health check
Node.js (ioredis)
// lib/health.ts
import Redis from 'ioredis'
let redis: Redis | null = null
function getRedis(): Redis {
if (!redis) {
redis = new Redis(process.env.REDIS_URL!, {
tls: process.env.REDIS_TLS === 'true' ? {} : undefined,
connectTimeout: 3000,
commandTimeout: 3000,
maxRetriesPerRequest: 1,
})
redis.on('error', (err) => {
console.error('Redis connection error:', err.message)
})
}
return redis
}
export async function checkRedis(): Promise<{ status: 'ok' | 'error'; latencyMs?: number; error?: string; info?: Record<string, string> }> {
const start = Date.now()
try {
const client = getRedis()
const pong = await client.ping()
if (pong !== 'PONG') {
return { status: 'error', error: `Unexpected PING response: ${pong}` }
}
const latencyMs = Date.now() - start
// Get basic memory info
const infoRaw = await client.info('memory')
const info: Record<string, string> = {}
for (const line of infoRaw.split('\r\n')) {
const [key, val] = line.split(':')
if (key && val) info[key] = val.trim()
}
return {
status: 'ok',
latencyMs,
info: {
usedMemoryHuman: info.used_memory_human,
maxMemoryHuman: info.maxmemory_human,
evictedKeys: info.evicted_keys,
connectedClients: info.connected_clients,
},
}
} catch (err: any) {
return { status: 'error', error: err.message }
}
}
Python (redis-py)
# health.py
import redis
import os
import time
_client = None
def get_redis():
global _client
if _client is None:
_client = redis.from_url(
os.environ['REDIS_URL'],
ssl=os.environ.get('REDIS_TLS', 'false').lower() == 'true',
socket_connect_timeout=3,
socket_timeout=3,
)
return _client
def check_redis() -> dict:
start = time.time()
try:
r = get_redis()
pong = r.ping()
if not pong:
return {'status': 'error', 'error': 'PING returned False'}
info = r.info('memory')
return {
'status': 'ok',
'latency_ms': round((time.time() - start) * 1000),
'used_memory_human': info.get('used_memory_human'),
'maxmemory_human': info.get('maxmemory_human', 'no limit'),
'evicted_keys': info.get('evicted_keys', 0),
}
except Exception as e:
return {'status': 'error', 'error': str(e)}
Step 2: Expose the health check in your API
// Express route
import { checkRedis } from '../lib/health'
app.get('/health', async (req, res) => {
const redisResult = await checkRedis()
const allOk = redisResult.status === 'ok'
res.status(allOk ? 200 : 503).json({
status: allOk ? 'ok' : 'degraded',
checks: { redis: redisResult },
timestamp: new Date().toISOString(),
})
})
Step 3: Alert on memory usage, not just connectivity
A PING returning PONG doesn't mean Redis is healthy — it means it's reachable. Add a memory threshold check:
export async function checkRedisHealth(): Promise<{ status: string; warning?: string }> {
const result = await checkRedis()
if (result.status === 'error') return result
// Parse memory usage
const used = parseInt(result.info?.usedMemoryHuman ?? '0')
const max = parseInt(result.info?.maxMemoryHuman ?? '0')
if (max > 0 && used / max > 0.85) {
return { ...result, warning: 'Memory usage above 85% — evictions likely soon' }
}
const evicted = parseInt(result.info?.evictedKeys ?? '0')
if (evicted > 0) {
return { ...result, warning: `${evicted} keys evicted — check memory limits` }
}
return result
}
Return warnings as a non-500 but include them in your health response body so your monitoring dashboard can surface them.
Step 4: Test your TLS connection specifically
# From your app server, test TLS connectivity directly
redis-cli -u "$REDIS_URL" --tls --cacert /etc/ssl/certs/ca-certificates.crt PING
# Or with openssl to check cert chain
openssl s_client -connect your-redis-host.redis.io:6380 -showcerts
If the cert chain fails, your redis client will silently fail to connect. Verify this as part of your deploy checklist.
Step 5: Set up external monitoring
- Go to vigilmon.online — free tier, no credit card.
- Create an HTTP(S) monitor.
- URL:
https://your-api.com/health - Interval: 60s
- Expected status: 200
- Add 2+ regions
- Set a latency alert at 500ms — Redis should respond in under 10ms normally; 500ms means something is wrong
Step 6: Use Redis Cloud's built-in alerts too
Redis Cloud has native alerting in the dashboard:
- Memory usage: alert at 75% and 90%
- Connection count: alert at 80% of limit
- Throughput: alert on unusual spikes
These are internal Redis metrics. Your external monitor covers connectivity from your app's perspective. Use both.
What healthy looks like
{
"status": "ok",
"checks": {
"redis": {
"status": "ok",
"latencyMs": 4,
"info": {
"usedMemoryHuman": "124.5M",
"maxMemoryHuman": "1.00G",
"evictedKeys": "0",
"connectedClients": "12"
}
}
}
}
Recap
- Create a shared Redis client — never create per-request clients in serverless.
- Health check with
PING+INFO memory— latency and memory tell you more than connectivity alone. - Alert on evicted keys > 0: silent evictions often mean session loss.
- Verify TLS cert chains explicitly, especially after infrastructure changes.
- Use Redis Cloud's built-in alerts for internal metrics, and vigilmon.online for external connectivity checks.
Redis Cloud keeps your data fast. External monitoring keeps you informed when it isn't.
Top comments (0)