Skip to content

Redis — Practical

async function getUser(id: string) {
const k = `user:${id}`;
const cached = await redis.get(k);
if (cached) return JSON.parse(cached);
const u = await db.users.find(id);
if (u) await redis.set(k, JSON.stringify(u), 'EX', 300);
return u;
}
async function updateUser(id: string, patch: any) {
const u = await db.users.update(id, patch);
await redis.del(`user:${id}`);
return u;
}
import crypto from 'crypto';
async function lock(key: string, ttl = 30) {
const token = crypto.randomUUID();
const ok = await redis.set(`lock:${key}`, token, 'NX', 'EX', ttl);
return ok ? token : null;
}
const RELEASE = `
if redis.call('get', KEYS[1]) == ARGV[1] then
return redis.call('del', KEYS[1])
else
return 0
end`;
async function unlock(key: string, token: string) {
return redis.eval(RELEASE, 1, `lock:${key}`, token);
}
local data = redis.call('HMGET', KEYS[1], 'tokens', 'ts')
local tokens = tonumber(data[1]) or tonumber(ARGV[3])
local ts = tonumber(data[2]) or tonumber(ARGV[1])
local elapsed = tonumber(ARGV[1]) - ts
tokens = math.min(tonumber(ARGV[3]), tokens + elapsed * tonumber(ARGV[2]))
local allowed = 0
if tokens >= 1 then tokens = tokens - 1; allowed = 1 end
redis.call('HMSET', KEYS[1], 'tokens', tokens, 'ts', ARGV[1])
redis.call('EXPIRE', KEYS[1], 60)
return allowed
async function allow(userId: string, limit = 100, windowSec = 60) {
const now = Date.now();
const k = `rl:${userId}`;
const cutoff = now - windowSec * 1000;
const m = redis.multi()
.zremrangebyscore(k, 0, cutoff)
.zadd(k, now, `${now}-${crypto.randomUUID()}`)
.zcard(k)
.expire(k, windowSec);
const [, , [, count]] = await m.exec();
return count <= limit;
}
const sub = redis.duplicate();
await sub.subscribe('orders:created');
sub.on('message', (chan, msg) => console.log(chan, msg));
await redis.publish('orders:created', JSON.stringify({ id: 1 }));
Terminal window
XADD orders * id 1 amount 100
XGROUP CREATE orders processors $ MKSTREAM
XREADGROUP GROUP processors w1 COUNT 10 BLOCK 5000 STREAMS orders >
XACK orders processors <id>
XPENDING orders processors
Terminal window
ZADD board 100 alice
ZADD board 250 bob
ZRANGE board 0 9 WITHSCORES REV
ZRANK board alice
ZINCRBY board 10 alice
Terminal window
redis-cli INFO replication
redis-cli INFO memory
redis-cli INFO stats
redis-cli SLOWLOG GET 10
redis-cli --bigkeys
redis-cli --latency
maxmemory 4gb
maxmemory-policy allkeys-lru
appendonly yes
appendfsync everysec
tcp-keepalive 300
  • KEYS * in prod (use SCAN).
  • Storing huge values (>1MB) — split or use external store.
  • Long-running Lua scripts — block Redis.
  • Treating Redis as primary DB without persistence + replication.
  • Connection-per-request — use a pool.
  • Node: ioredis (cluster, pipelining), redis v4.
  • Python: redis-py.
  • Go: go-redis.
  • Java: lettuce, jedis.