
Krati JoshiIf you're preparing for a Node.js backend interview, Redis is one of those technologies you should...
If you're preparing for a Node.js backend interview, Redis is one of those technologies you should understand beyond just knowing that it's "fast."
Redis is commonly used for caching, sessions, rate limiting, counters, Pub/Sub, distributed coordination, and fast data access.
In this article, I'll cover the Redis concepts that are especially important for backend development and interviews.
Redis is an in-memory data store that provides several useful data structures and very fast operations.
Instead of primarily reading every value from disk like a traditional relational database, Redis keeps its working dataset in memory.
A common backend architecture looks like:
Client
β
Node.js / Express API
β
Redis
β
Database
Redis can reduce the number of requests that reach the primary database.
The major reason is that Redis is designed around in-memory data access.
Instead of:
Application β Disk-based Database β Response
we can have:
Application β Redis RAM β Response
This makes Redis especially useful when the same data is requested repeatedly.
Redis isn't limited to simple key-value strings.
Some important data types are:
| Data Type | Common Use |
|---|---|
| String | Cache, tokens, counters |
| Hash | User/object data |
| List | Queues, recent items |
| Set | Unique values |
| Sorted Set | Leaderboards/ranking |
| Stream | Event/message processing |
SET user:1:name "Krati"
GET user:1:name
HSET user:1 name "Krati" role "Backend Developer"
Hashes are useful when storing multiple fields belonging to an object.
SADD online_users 101
SADD online_users 102
Sets automatically maintain uniqueness.
ZADD leaderboard 1000 user101
ZADD leaderboard 1500 user102
Useful for rankings and leaderboards.
When Redis is used as a cache, we usually don't want data to remain forever.
We can set an expiration time:
SET user:1 "some-data" EX 300
The key expires after 300 seconds.
Check the remaining time:
TTL user:1
TTL is important because it helps:
This is one of the most important Redis concepts for backend interviews.
Suppose we have:
GET /users/101
Instead of querying the database every time:
Request
β
Database
β
Response
we use Redis.
Request
β
Redis
β
Cache HIT β Return data
If Redis doesn't contain the data:
Request
β
Redis
β
CACHE MISS
β
Database
β
Store result in Redis
β
Return response
This is called the Cache-Aside pattern.
The application is responsible for reading and populating the cache.
The requested data exists in Redis.
Request
β
Redis
β
HIT
β
Return
The database doesn't need to be queried.
The requested data isn't present.
Request
β
Redis
β
MISS
β
Database
β
Redis SET
β
Return
A useful metric is:
Cache Hit Ratio =
Cache Hits / (Cache Hits + Cache Misses)
One of the hardest problems with caching is keeping cached data consistent with the database.
Suppose:
Database:
User name = Alice
Redis:
User name = Alice
Now the user changes their name:
Database:
Alice β Bob
But Redis still contains:
Alice
Now we have stale cache data.
A common solution is:
UPDATE Database
β
DELETE Redis key
For example:
await db.user.update({
where: { id },
data: updateData
});
await redis.del(`user:${id}`);
The next request will cause a cache miss and fetch the latest data from the database.
The official Node.js Redis client is node-redis.
Basic setup:
import { createClient } from "redis";
const redis = createClient({
url: process.env.REDIS_URL
});
redis.on("error", (err) => {
console.error("Redis error:", err);
});
await redis.connect();
Set a value:
await redis.set("name", "Krati");
Get it:
const name = await redis.get("name");
Set with TTL:
await redis.set("otp:123", "456789", {
EX: 300
});
Delete:
await redis.del("otp:123");
Redis is also very useful for implementing API rate limiting.
Imagine:
POST /login
We want to allow only:
5 attempts / minute
We can maintain a counter in Redis.
Conceptually:
Request
β
Redis INCR
β
Check count
β
Limit exceeded?
βββ YES β Reject
βββ NO β Continue
Example:
INCR login:user123
EXPIRE login:user123 60
Redis works well here because operations such as INCR are atomic.
It's also shared across multiple Node.js instances:
βββ Node Server 1
Client βββββββΌββ Node Server 2
βββ Node Server 3
β
Redis
All servers can use the same rate-limit state.
When an application has multiple servers, storing sessions only in one server's memory can become problematic.
Instead:
βββ Server 1
Client ββββββββββΌββ Server 2
βββ Server 3
β
Redis
All servers can access the same session information.
Redis documentation specifically describes Redis as a useful shared session store for stateless application servers.
An operation is atomic when it executes as one indivisible operation from the perspective of other Redis commands.
For example:
INCR counter
Instead of doing:
GET counter
β
counter + 1
β
SET counter
we can use:
INCR counter
This is especially useful for:
Redis can also provide a publish/subscribe mechanism.
Architecture:
Publisher
β
Redis Channel
β
Subscribers
Example:
PUBLISH notifications "Order created"
Another service can subscribe:
SUBSCRIBE notifications
Useful for:
Redis Pub/Sub is not a durable message queue.
If a subscriber is disconnected, it can miss messages.
For durable event processing, Redis Streams are a better concept to study. Redis Streams support persisted entries and consumer groups.
Redis is primarily memory-based, but it supports persistence.
Two important mechanisms are:
RDB = Redis Database snapshot
Redis periodically creates a point-in-time snapshot of the dataset.
Redis
β
Snapshot
β
Disk
Advantages:
Disadvantage:
AOF = Append Only File
Instead of only taking periodic snapshots, Redis records write operations in an append-only log.
SET user:1 Alice
INCR counter
DEL user:2
β
AOF
β
Disk
When Redis restarts, the recorded operations can be replayed to reconstruct the dataset.
AOF durability depends on its fsync configuration; stronger durability generally comes with more I/O cost.
| RDB | AOF |
|---|---|
| Snapshot | Write log |
| Point-in-time | Records changes |
| Usually more compact | Usually larger |
| Good for backups | Better durability options |
| Can lose recent changes | Less data loss depending on fsync |
Redis data lives primarily in memory, so memory management is important.
If Redis reaches its configured memory limit, an eviction policy can determine what happens to keys.
Some policies include:
noeviction
allkeys-lru
volatile-lru
allkeys-lfu
Interview question:
What happens when Redis memory is full?
Answer:
Redis applies the configured memory policy. Depending on the policy, it may evict eligible keys or reject writes.
Consider a popular API:
1000 requests
β
Same cached key
β
Cache expires
β
1000 CACHE MISS
β
1000 Database queries
The database can suddenly become overloaded.
This is called a cache stampede.
Possible solutions:
Redis can also be used for distributed coordination.
A basic locking concept is:
SET lock:payment 123 NX EX 30
Here:
NX β set only if the key doesn't existEX 30 β lock expires after 30 secondsThis can help ensure that multiple application instances don't simultaneously perform the same critical operation.
For production-grade distributed locking, however, you need to consider ownership, expiry, failures, and Redis topology rather than treating a single command as a complete locking solution.
A typical backend might look like:
ββββββββββββββββ
β Client β
ββββββββ¬ββββββββ
β
ββββββββββββββββ
β Load Balancerβ
ββββββββ¬ββββββββ
β
βββββββββββββ΄ββββββββββββ
β β
Node.js Server 1 Node.js Server 2
β β
βββββββββββββ¬ββββββββββββ
β
Redis
β
Database
Redis can handle:
while the database remains the primary source of durable business data in many architectures.
Before a Node.js backend interview, remember:
Redis
β
In-memory data store
β
Fast
β
Cache
β
TTL
β
Cache Hit / Miss
β
Cache-Aside
β
Cache Invalidation
β
Rate Limiting
β
Sessions
β
Atomic Operations
β
Pub/Sub
β
Streams
β
RDB / AOF
β
Eviction
β
Cache Stampede
β
Distributed Lock
1. Why is Redis fast?
Because it is designed around in-memory data access and efficient data structures.
2. Redis vs PostgreSQL?
Redis is commonly used for fast access, caching, sessions and transient/shared state; PostgreSQL is generally used for durable relational business data.
3. What is Cache-Aside?
Application checks Redis β on miss queries DB β stores result in Redis β returns response.
4. How do you handle stale cache?
Invalidate or update the cache when the underlying database data changes.
5. Why Redis for rate limiting?
Fast shared storage plus atomic operations such as INCR.
6. RDB vs AOF?
RDB = snapshots.
AOF = append-only write log.
7. What happens if Redis goes down?
For cache use cases, the application should ideally fall back to the database where appropriate, with proper timeouts, error handling and monitoring.
Redis isn't just a "cache."
For a backend developer, think of Redis as a high-speed shared data layer that can solve several problems:
Caching β Reduce DB load
TTL β Automatically expire data
Rate limiting β Control requests
Sessions β Share session state
Counters β Atomic increments
Pub/Sub β Lightweight messaging
Streams β Durable event processing
Locks β Distributed coordination
Persistence β RDB / AOF
If you're preparing for a 2+ YOE Node.js interview, focus less on memorizing commands and more on being able to explain why Redis is used, where it fits in the architecture, cache invalidation, failure scenarios, and the trade-offs involved.
Full CheatSheet