const { createClient } = require('redis');
const client = createClient({ url: process.env.REDIS_URL || 'redis://localhost:6379' });
client.on('error', (err) => console.error('Redis error:', err));
await client.connect();
await client.set('greeting', 'hello');
const value = await client.get('greeting');
Topics
40
Advanced Node.js
Architecture & Design Patterns
Async Patterns
Authentication & Authorization
Authentication & Authorization (JWT, OAuth, Passport)
Background Jobs & Queues
Caching
Caching with Redis
Child Processes & Process Management
CLI Tools & Scripting with Node.js
Cloud & DevOps
Clustering & Worker Threads
Core Node.js Modules
Databases
Databases & ORMs (MongoDB/Mongoose, SQL/Sequelize)
Debugging & Diagnostics
Deployment & Process Managers (PM2)
Docker & Containerization for Node.js
Docker & Deployment
Email & Notifications
Environment Variables & Configuration
Error Handling
Event Loop & Non-blocking IO
Events & EventEmitter
Express & Middleware
File System & File Processing
File System (fs) Module
File Uploads & Media Processing
Git & Project Management
Global Objects & the process Object
GraphQL
GraphQL with Node.js
HTTP & HTTPS Modules
HTTP & Web Servers
Logging & Monitoring
Message Queues (RabbitMQ & Kafka)
Microservices Architecture with Node.js
Node.js Fundamentals & Runtime Architecture
Path & OS Modules
Performance Optimization & Profiling
Caching with Redis
5 questions found
The node-redis package (v4+) provides a promise-based client -- you create a client with createClient(), specifying the connection URL, call connect() to establish the connection, and then use async methods like get(), set(), and del() to interact with Redis, with the client automatically handling connection pooling internally for you.
Real-world example
A Node.js API establishes a single shared Redis client at application startup, reusing that one connection across every request handler rather than creating a new connection per request, which would quickly exhaust Redis's available connections under load.
Databases & ORMs (MongoDB/Mongoose
SQL/Sequelize);Error Handling
What Redis data structures beyond simple string values are useful for a Node.js application, and what are they typically used for?
IntermediateBeyond simple key-value strings, Redis supports Hashes (field-value maps within a single key, efficient for representing an object like a user profile), Lists (ordered collections, useful for simple queues via LPUSH/RPOP), Sets (unordered unique collections, useful for tracking things like unique online user IDs), Sorted Sets (unique members each with a score, ideal for leaderboards or rate-limiting windows), and Streams (an append-only log, useful for simple event/message processing).
// Hash: representing a user profile efficiently
await client.hSet('user:123', { name: 'Alice', email: 'alice@example.com' });
const name = await client.hGet('user:123', 'name');
// Sorted set: a leaderboard
await client.zAdd('leaderboard', { score: 4500, value: 'user:123' });
const top10 = await client.zRangeWithScores('leaderboard', 0, 9, { REV: true });
Real-world example
A gaming platform uses a Redis Sorted Set to maintain a real-time leaderboard, letting it efficiently query 'top 10 players' or 'this player's current rank' with a single fast command, rather than repeatedly sorting a large dataset from a traditional database.
Databases & ORMs (MongoDB/Mongoose
SQL/Sequelize);Performance Optimization & Profiling
How would you implement a distributed lock using Redis to coordinate access to a shared resource across multiple Node.js instances?
AdvancedA distributed lock uses Redis's atomic SET with the NX (only set if not exists) and EX (expiration) options to acquire a lock -- only one instance can successfully set the key, guaranteeing mutual exclusion, with the expiration ensuring the lock is automatically released even if the instance holding it crashes without explicitly releasing it, preventing a permanently stuck lock.
async function acquireLock(resource, ttlMs = 10000) {
const lockId = crypto.randomUUID();
const acquired = await client.set(`lock:${resource}`, lockId, { NX: true, PX: ttlMs });
return acquired ? lockId : null;
}
async function releaseLock(resource, lockId) {
// Only release if we still hold the lock (using a Lua script for atomicity)
const script = `if redis.call('get', KEYS[1]) == ARGV[1] then return redis.call('del', KEYS[1]) else return 0 end`;
await client.eval(script, { keys: [`lock:${resource}`], arguments: [lockId] });
}
Real-world example
A daily report-generation job that must run exactly once, even though it's triggered from multiple redundant scheduler instances for high availability, uses a Redis distributed lock so only the first instance to acquire the lock actually runs the job, while the others detect the lock is held and skip execution.
Background Jobs & Queues;Message Queues (RabbitMQ & Kafka)
How would you implement a simple rate limiter using Redis's INCR command with expiration?
IntermediateA fixed-window rate limiter increments a counter keyed by the client's identifier and current time window, setting an expiration on first creation of that key -- if the counter exceeds the allowed limit within the window before it expires, further requests are rejected; this leverages Redis's atomic INCR to safely handle concurrent requests from the same client without race conditions.
async function checkRateLimit(userId, limit = 100, windowSeconds = 60) {
const key = `ratelimit:${userId}:${Math.floor(Date.now() / (windowSeconds * 1000))}`;
const count = await client.incr(key);
if (count === 1) await client.expire(key, windowSeconds);
return count <= limit;
}
Real-world example
A public API enforces a limit of 100 requests per minute per API key using this Redis-backed counter pattern, rejecting requests with a 429 status once a client exceeds the threshold within the current one-minute window, resetting automatically as each window's key expires.
HTTP & HTTPS Modules;Security
What is Redis Pub/Sub, and how would a Node.js application use it to broadcast real-time events across multiple server instances?
IntermediateRedis Pub/Sub lets clients subscribe to named channels and receive messages published to those channels in real time -- useful for broadcasting an event (like a chat message or a live notification) to every connected server instance simultaneously, which matters for something like a WebSocket-based chat application running multiple instances behind a load balancer, since a message published by one instance needs to reach clients connected to every other instance too.
const subscriber = client.duplicate();
await subscriber.connect();
await subscriber.subscribe('chat-room-1', (message) => {
broadcastToLocalWebSocketClients(JSON.parse(message));
});
// Any instance can publish, and all subscribed instances receive it
await client.publish('chat-room-1', JSON.stringify({ user: 'Alice', text: 'Hello!' }));
Real-world example
A chat application running four load-balanced Node.js instances uses Redis Pub/Sub so that when a message is sent by a user connected to instance 2, it's published to Redis and received by all four instances, letting each broadcast it to its own locally-connected WebSocket clients regardless of which instance they're connected to.
WebSockets & Real-Time Communication;Clustering & Worker Threads