From Cache to Real-Time Magic: Getting Started with Redis


Ever wondered why your app takes 300ms to respond, even after you’ve optimized your code? It's not always your logic — it's your data access. Traditional databases can bottleneck performance when they're hit on every request. That’s where Redis comes in — an in-memory data store that turns milliseconds into microseconds.
In this article, we'll explore how Redis can dramatically boost your application's performance through caching, pub/sub, and real-time data handling.
Introduction
What is Redis?
Redis is an open-source, in-memory data store often used as a cache, database, and message broker. It stores data in RAM instead of disk, making it extremely fast, with response times in microseconds.
Key features:
In-memory storage → Lightning-fast read/write performance.
Caching → Offloads pressure from databases and speeds up apps.
Pub/Sub messaging → Supports publish/subscribe for real-time messaging.
Rich data structures → Redis isn’t just a key-value store; it supports advanced data structures.
Persistence options → It can optionally persist data using RDB (Snapshotting) and AOF (Append-Only File)
Lightweight & Easy to Use → Redis provides a powerful CLI and client libraries available in almost every language.
Why Use Redis?
Redis is not just another database — it’s a powerful tool for building fast, scalable, and responsive backend systems. Here’s why you should consider using Redis in your stack:
Extremely High Speed
Redis stores everything in memory, so reads and writes happen in under 1 millisecond.
Perfect for real-time applications like live chats, analytics, or gaming.
Caching Powerhouse
Reduce the load on your primary database by caching frequently accessed data.
Easily implement API response caching, session storage, user data, etc.
Real-Time Messaging with Pub/Sub
- Built-in Publish/Subscribe system enables real-time notifications, chats, and event-driven architecture.
Advanced Data Structures
Native support for lists, sets, hashes, sorted sets, bitmaps, etc.
Helps solve complex backend problems without extra logic in your app.
Reliable Persistence
- Though it’s in-memory, Redis supports data persistence (RDB, AOF), so your data isn’t lost after restarts.
Easily Scalable
- Redis supports replication, clustering, and horizontal scaling to meet enterprise-level demands.
Simple Setup
Easy to install and integrate.
Available client libraries for almost every language: Node.js, Python, Go, Java, C#, etc.
How to use Redis?
Alright, enough of the technical details about Redis. Now let’s dive deep into how to use Redis on our real-world projects.
Installing Redis
You can always refer to the official Redis documentation on how to install Redis on your system. But in this article, I’ll be guiding you on how to install it using Docker so that it works similarly on every machine, even if the OS is different.
Step 1: Make sure you have Docker installed on your system
Run this command to check:
docker --version
If this command returns something like this, then Docker is installed on your system
Docker version 27.5.1, build 9f9e405
Otherwise, install Docker Desktop first.
Step 2: Run Docker Desktop on your system
Step 3: Run Redis Open Source on Docker
To start the Redis Open Source server, run the following command in your terminal:
docker run -d --name redis -p 6379:6379 redis:latest
Once the command runs successfully, you will see the following on the Docker Desktop app.
Step 4: Connect to Redis CLI
You can now connect to the server using the
redis-cli
, just as you connect to any Redis instance.You can run
redis-cli
directly from the Docker container, using this command:docker exec -it redis redis-cli
Run the following command to check if it is connected properly or not:
ping
If it returns
PONG
, it meansredis-cli
is connected successfully.Now you can run any Redis CLI commands.
Hands On: Getting Started with Redis
In this section, you will learn about some basic Redis commands with some examples.
Redis CLI commands
NOTE: Before introducing to Redis CLI commands, I’ll guide you on how to connect Redis to your Node.js (you can pick other languages too) code.
Using Redis in JavaScript code
Install
redis
NPM packagenpm install redis
Import it into your code and create a
client
import { createClient } from 'redis'; const client = createClient(); client.on('error', err => console.log('Redis Client Error', err)); await client.connect(); // connects to redis on port 6379 // WRITE YOUR CODE BELOW THIS
Since we have set up our Redis, we can now start using Redis commands
Basic Redis commands
SET
Stores a key-value pair
Example
- CLI
SET bike:1 "Yamaha R1"
"OK"
SET bike:2 "BMW S1000RR"
"OK"
- Node.js
await client.set('bike:1', 'Yamaha R1');
await client.set('bike:2', 'BMW S1000RR');
GET
Retrieve the value of a key
Example
- CLI
GET bike:2
"BMW S1000RR"
- Node.js
const value = await client.get('bike:1');
console.log(value); // returns 'BMW S1000RR'
DEL
Delete a key
Example
- CLI
SET key1 "Hello"
"OK"
SET key2 "World"
"OK"
DEL key1 key2 key3
(integer) 2
- Node.js
await client.set('key1', 'Hello');
await client.set('key2', 'World');
const delRes = await client.del(['key1', 'key2', 'key3']);
console.log(delRes); // 2
EXPIRE
Set a timeout on key. After the timeout has expired, the key will automatically be deleted.
Example
- CLI
SET mykey "Hello"
"OK"
EXPIRE mykey 10
(integer) 1
GET mykey
"Hello"
# After 15 seconds
GET mykey
(nil)
- Node.js
await client.set('mykey', 'Hello');
await client.expire('mykey', 10);
const res1 = await client.get('mykey');
console.log(res1); // Hello
setTimeout(async () => {
const res2 = await client.get('mykey');
console.log(res2); // null
}, 15000);
TTL
Returns the remaining time to live of a key that has a timeout.
Example
- CLI
SET mykey "Hello"
"OK"
EXPIRE mykey 10
(integer) 1
TTL mykey
(integer) 10
# After 15 seconds
TTL mykey
(integer) -2
- Node.js
await client.set('mykey', 'Hello');
await client.expire('mykey', 10);
const res1 = await client.ttl('mykey');
console.log(res1); // 10
setTimeout(async () => {
const res2 = await client.ttl('mykey');
console.log(res2); // -2
}, 15000);
INCR
Increments the number stored at key by one. If the key does not exist, it is set to
0
before performing the operation. An error is returned if the key contains a value of the wrong type or contains a string that can not be represented as integer.Example
- CLI
SET mykey "10"
"OK"
INCR mykey
(integer) 11
GET mykey
"11"
- Node.js
await client.set("mykey", "10");
const value1 = await client.incr("mykey");
console.log(value1); // 11
DECR
Decrements the number stored at key by one. If the key does not exist, it is set to
0
before performing the operation. An error is returned if the key contains a value of the wrong type or contains a string that can not be represented as integer.Example
- CLI
SET mykey "10"
"OK"
DECR mykey
(integer) 9
GET mykey
"9"
SET mykey "234293482390480948029348230948"
"OK"
DECR mykey
(error) value is not an integer or out of range
- Node.js
await client.set("mykey", "10");
const value1 = await client.decr("mykey");
console.log(value1); // 9
LPUSH
Add element to the start of a list
Example
- CLI
LPUSH mylist "world"
(integer) 1
LPUSH mylist "hello"
(integer) 2
LRANGE mylist 0 -1
1) "hello"
2) "world"
- Node.js
const res1 = await client.lPush('mylist', 'world');
console.log(res1); // 1
const res2 = await client.lPush('mylist', 'hello');
console.log(res2); // 2
const res3 = await client.lRange('mylist', 0, -1);
console.log(res3); // [ 'hello', 'world' ]
RPUSH
Add element to the end of a list
Example
- CLI
RPUSH mylist "hello"
(integer) 1
RPUSH mylist "world"
(integer) 2
LRANGE mylist 0 -1
1) "hello"
2) "world"
- Node.js
const res14 = await client.rPush('mylist', 'hello');
console.log(res14); // 1
const res15 = await client.rPush('mylist', 'world');
console.log(res15); // 2
const res16 = await client.lRange('mylist', 0, -1);
console.log(res16); // [ 'hello', 'world' ]
FLUSHALL
Delete all keys in all databases (use with caution!)
It is possible to use one of the following modifiers to dictate the flushing mode explicitly:
ASYNC
: flushes the databases asynchronouslySYNC
: flushes the databases synchronously
Example
- CLI
FLUSHALL SYNC
- Node.js
const res1 = await client.flushAll('SYNC'); // or ASYNC
console.log(res1); // OK
const res2 = await client.keys('*');
console.log(res2); // []
There are many more commands. If you want to learn about them, go check out the Redis official docs.
Common use cases
Caching
Caching is the most common use case for Redis. By storing frequently accessed data in memory, Redis significantly reduces latency and decreases the load on your primary database. This results in a faster and more responsive application.
The "cache-aside" pattern is a popular caching strategy where the application first checks the Redis cache for data. If the data is present (a cache hit), it's returned to the client. If not (a cache miss), the application queries the primary database, stores the result in Redis, and then returns it to the client.
Session Management
In a distributed or microservices architecture, managing user sessions can be challenging. Storing session data on a single server can lead to issues if that server fails or if traffic is routed to a different server. Redis provides a centralized and highly available key-value store for session data. This ensures that a user's session is consistent across multiple application servers.
Real-time Chat and Messaging
Redis can act as a lightweight, real-time message broker using its Pub/Sub capabilities. This is suitable for chat applications, real-time notifications, or any scenario where a sender needs to broadcast messages to multiple receivers.
Conclusion
Redis isn't just another tool in your tech stack — it's a performance multiplier that can transform slow applications into lightning-fast experiences. Throughout this article, we've seen how Redis addresses the fundamental bottleneck that plagues many applications: slow data access.
From basic key-value operations to advanced pub/sub messaging, Redis offers a versatile solution for multiple performance challenges. Whether you're implementing caching to reduce database load, managing user sessions across distributed systems, or building real-time features like chat applications, Redis provides the speed and reliability your users expect.
The beauty of Redis lies in its simplicity. With just a few commands, you can implement caching strategies that would otherwise require complex infrastructure. The Docker setup we covered makes it accessible for development, while Redis's enterprise features ensure it scales with your production needs
What’s next?
Now that you understand Redis fundamentals, consider these next steps:
Implement Redis caching for your most frequently accessed database queries
Dive deeper into Redis data structures like sorted sets, bitmaps, and streams for more complex use cases
Remember, the difference between a good application and a great one often comes down to performance. Redis gives you the tools to deliver that exceptional user experience where every millisecond counts.
Thank you for taking the time to read this comprehensive guide to Redis! I hope this article has given you the confidence and knowledge to start leveraging Redis in your own projects.
If you found this helpful, I'd love to hear about your Redis implementation experiences or any questions you might have. Feel free to share your thoughts, and don't hesitate to reach out if you'd like to see more in-depth tutorials on specific Redis features.
Subscribe to my newsletter
Read articles from Debangshu Das directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by
