Troubleshooting

Solutions to common issues with Redis connections and performance.

Connection Issues#

"ECONNREFUSED" or "Connection refused"#

Cause: Can't reach the Redis server.

Solutions:

  1. Check your connection URL:
TypeScript
// Make sure you're using the correct URL console.log('Connecting to:', process.env.ARCTICKEY_URL?.replace(/:[^:@]+@/, ':***@'));
  1. Verify network connectivity:
Terminal
# Test if you can reach the host nc -zv your-db.arctickey.com 6379
  1. Check for firewall rules blocking port 6379

  2. Ensure TLS is enabled - use rediss:// not redis://


"NOAUTH Authentication required"#

Cause: Missing or incorrect password.

Solutions:

  1. Check your connection URL includes password:
TEXT
rediss://default:YOUR_PASSWORD@host:6379
  1. Verify the password is correct in your dashboard

  2. Check for special characters that need URL encoding:

TypeScript
// If password contains special chars, encode it const password = encodeURIComponent('pass@word!'); const url = `rediss://default:${password}@host:6379`;

"WRONGPASS invalid username-password pair"#

Cause: Password is incorrect or has been rotated.

Solutions:

  1. Go to your Arctickey dashboard
  2. Check the current password
  3. Update your environment variables
  4. Redeploy your application

"Connection timeout"#

Cause: Slow network or connection pool exhausted.

Solutions:

  1. Increase connection timeout:
TypeScript
const redis = new Redis({ ...options, connectTimeout: 10000, // 10 seconds });
  1. Check your connection pool size:
TypeScript
// For ioredis const redis = new Redis({ ...options, maxRetriesPerRequest: 3, retryStrategy(times) { return Math.min(times * 50, 2000); }, });
  1. Check for connection leaks - ensure you're not creating too many connections

"TLS/SSL handshake failed"#

Cause: TLS configuration issue.

Solutions:

  1. Use rediss:// URL scheme:
TypeScript
// ✅ Correct const url = 'rediss://default:pass@host:6379'; // ❌ Wrong const url = 'redis://default:pass@host:6379';
  1. For self-signed certs (not needed for Arctickey):
TypeScript
const redis = new Redis({ ...options, tls: { rejectUnauthorized: false, // Only for testing! }, });

Performance Issues#

Slow commands#

Diagnosis:

TypeScript
// Log slow commands redis.on('ready', () => { redis.config('SET', 'slowlog-log-slower-than', 10000); // 10ms }); // Check slow log const slowLog = await redis.slowlog('GET', 10); console.log(slowLog);

Common causes:

  1. KEYS command - use SCAN instead:
TypeScript
// ❌ Slow - blocks server const keys = await redis.keys('user:*'); // ✅ Fast - iterates without blocking let cursor = '0'; const keys = []; do { const [nextCursor, batch] = await redis.scan(cursor, 'MATCH', 'user:*', 'COUNT', 100); cursor = nextCursor; keys.push(...batch); } while (cursor !== '0');
  1. Large values - keep values under 100KB:
TypeScript
// Check value size before storing const value = JSON.stringify(data); if (value.length > 100000) { console.warn('Large value detected:', value.length, 'bytes'); }
  1. Missing indexes - use the right data structure:
TypeScript
// ❌ Slow - scanning all users const users = await redis.hgetall('users'); const activeUsers = Object.entries(users).filter(([_, u]) => u.active); // ✅ Fast - separate set for active users await redis.sadd('users:active', visitorId); const activeUsers = await redis.smembers('users:active');

High memory usage#

Diagnosis:

TypeScript
const info = await redis.info('memory'); console.log(info); // Look for: used_memory_human, maxmemory

Solutions:

  1. Set TTLs on all keys:
TypeScript
// Always set expiry await redis.setex('key', 3600, 'value'); // Or add to existing keys await redis.expire('key', 3600);
  1. Find large keys:
Terminal
# Using redis-cli redis-cli --bigkeys
  1. Use appropriate data structures:
TypeScript
// Store object fields, not huge JSON // ❌ Less efficient await redis.set('user:123', JSON.stringify({ name: 'Alice', email: '...', ... })); // ✅ More efficient for partial reads await redis.hset('user:123', { name: 'Alice', email: '...' });
  1. Compress large values:
TypeScript
import { gzip, gunzip } from 'zlib'; import { promisify } from 'util'; const compress = promisify(gzip); const decompress = promisify(gunzip); // Store compressed const compressed = await compress(JSON.stringify(largeData)); await redis.set('key', compressed.toString('base64')); // Retrieve and decompress const data = await redis.get('key'); const decompressed = await decompress(Buffer.from(data, 'base64')); const parsed = JSON.parse(decompressed.toString());

Too many connections#

Cause: Creating new connections instead of reusing.

Solutions:

  1. Use a singleton connection:
TypeScript
// lib/redis.ts import Redis from 'ioredis'; let redis: Redis | null = null; export function getRedis() { if (!redis) { redis = new Redis(process.env.ARCTICKEY_URL); } return redis; }
  1. For serverless, use connection pooling:
TypeScript
// Vercel/Lambda - connection per invocation import Redis from 'ioredis'; const redis = new Redis(process.env.ARCTICKEY_URL, { maxRetriesPerRequest: 1, lazyConnect: true, }); export async function handler() { await redis.connect(); // ... use redis await redis.quit(); }
  1. Check max connections in your plan:
    • Free: 10 connections
    • Starter: 50 connections
    • Growth: 200 connections

Error Messages#

"OOM command not allowed"#

Cause: Memory limit reached.

Solutions:

  1. Upgrade to a larger plan
  2. Delete unused keys
  3. Set TTLs on keys
  4. Reduce value sizes

"BUSY Redis is busy running a script"#

Cause: Long-running Lua script blocking server.

Solutions:

  1. Optimize your Lua scripts
  2. Break into smaller operations
  3. Use SCRIPT KILL to stop runaway scripts

"READONLY You can't write against a read only replica"#

Cause: Writing to a read replica.

Solutions:

  1. Ensure you're connecting to the primary instance
  2. Check your connection URL is correct

Debugging Tips#

Log all commands#

TypeScript
const redis = new Redis(process.env.ARCTICKEY_URL); redis.on('connect', () => console.log('Redis connected')); redis.on('error', (err) => console.error('Redis error:', err)); redis.on('close', () => console.log('Redis connection closed')); // Log all commands (development only!) if (process.env.NODE_ENV === 'development') { const originalSendCommand = redis.sendCommand.bind(redis); redis.sendCommand = (command) => { console.log('Redis:', command.name, command.args); return originalSendCommand(command); }; }

Check connection status#

TypeScript
console.log('Status:', redis.status); // 'connecting', 'connect', 'ready', 'close', 'reconnecting', 'end' const ping = await redis.ping(); console.log('Ping:', ping); // 'PONG'

Monitor in real-time#

TypeScript
// See all commands in real-time (don't use in production!) const monitor = await redis.monitor(); monitor.on('monitor', (time, args) => { console.log(time, args); });

Getting Help#

If you're still stuck:

  1. Check the status page for any ongoing incidents
  2. Search the docs - most issues are covered
  3. Email support - hello@arctickey.com
  4. Include these details:
    • Error message (full stack trace)
    • Your database region
    • Code snippet (remove passwords!)
    • When the issue started