# 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**](https://redis.io/) 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**.

![](https://miro.medium.com/v2/resize:fit:1200/1*i1d88Q8NNrRv6kjf7Ssw4g.png align="center")

### 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:

1. **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.
        
2. **Caching Powerhouse**
    
    * Reduce the load on your primary database by caching frequently accessed data.
        
    * Easily implement **API response caching**, **session storage**, **user data**, etc.
        
3. **Real-Time Messaging with Pub/Sub**
    
    * Built-in **Publish/Subscribe** system enables real-time notifications, chats, and event-driven architecture.
        
4. **Advanced Data Structures**
    
    * Native support for **lists, sets, hashes, sorted sets, bitmaps**, etc.
        
    * Helps solve complex backend problems without extra logic in your app.
        
5. **Reliable Persistence**
    
    * Though it’s in-memory, Redis supports **data persistence** (RDB, AOF), so your data isn’t lost after restarts.
        
6. **Easily Scalable**
    
    * Redis supports **replication**, **clustering**, and **horizontal scaling** to meet enterprise-level demands.
        
7. **Simple Setup**
    
    * Easy to install and integrate.
        
    * Available client libraries for **almost every language**: Node.js, Python, Go, Java, C#, etc.
        

![](https://api.profil-software.com/media/images/6_vZKXyEX.png align="center")

---

# 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](https://redis.io/docs/latest/operate/oss_and_stack/install/install-stack/) on how to install Redis on your system. But in this article, I’ll be guiding you on how to install it using [Docker](https://www.docker.com/) 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:
    
    ```bash
    docker --version
    ```
    
    If this command returns something like this, then Docker is installed on your system
    
    ```bash
    Docker version 27.5.1, build 9f9e405
    ```
    
    Otherwise, install [Docker Desktop](https://docs.docker.com/get-started/get-docker/) 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:
    
    ```bash
    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.
    
    ![](https://cdn.hashnode.com/res/hashnode/image/upload/v1749543577527/256bd3c2-fc2a-4f98-a9fd-8fe9df537825.png align="center")
    

### 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:
    
    ```bash
    docker exec -it redis redis-cli
    ```
    
    Run the following command to check if it is connected properly or not:
    
    ```bash
    ping
    ```
    
    If it returns `PONG`, it means `redis-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 package
    
    ```bash
    npm install redis
    ```
    
* Import it into your code and create a `client`
    
    ```javascript
    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

1. **SET**
    
    > Stores a key-value pair
    
    **Example**
    
    * CLI
        
    
    ```bash
    SET bike:1 "Yamaha R1"
    "OK"
    
    SET bike:2 "BMW S1000RR"
    "OK"
    ```
    
    * Node.js
        
    
    ```javascript
    await client.set('bike:1', 'Yamaha R1');
    await client.set('bike:2', 'BMW S1000RR');
    ```
    
2. **GET**
    
    > Retrieve the value of a key
    
    **Example**
    
    * CLI
        
    
    ```bash
    GET bike:2
    "BMW S1000RR"
    ```
    
    * Node.js
        
    
    ```javascript
    const value = await client.get('bike:1');
    console.log(value);    // returns 'BMW S1000RR'
    ```
    
3. **DEL**
    
    > Delete a key
    
    **Example**
    
    * CLI
        
    
    ```bash
    SET key1 "Hello"
    "OK"
    SET key2 "World"
    "OK"
    DEL key1 key2 key3
    (integer) 2
    ```
    
    * Node.js
        
    
    ```javascript
    await client.set('key1', 'Hello');
    await client.set('key2', 'World');
    
    const delRes = await client.del(['key1', 'key2', 'key3']);
    console.log(delRes); // 2
    ```
    
4. **EXPIRE**
    
    > Set a timeout on key. After the timeout has expired, the key will automatically be deleted.
    
    **Example**
    
    * CLI
        
    
    ```bash
    SET mykey "Hello"
    "OK"
    EXPIRE mykey 10
    (integer) 1
    GET mykey
    "Hello"
    
    # After 15 seconds
    GET mykey
    (nil)
    ```
    
    * Node.js
        
    
    ```javascript
    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);
    ```
    
5. **TTL**
    
    > Returns the remaining time to live of a key that has a timeout.
    
    Example
    
    * CLI
        
    
    ```bash
    SET mykey "Hello"
    "OK"
    
    EXPIRE mykey 10
    (integer) 1
    
    TTL mykey
    (integer) 10
    
    # After 15 seconds
    TTL mykey
    (integer) -2
    ```
    
    * Node.js
        
    
    ```javascript
    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);
    ```
    
6. **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
        
    
    ```bash
    SET mykey "10"
    "OK"
    
    INCR mykey
    (integer) 11
    
    GET mykey
    "11"
    ```
    
    * Node.js
        
    
    ```javascript
    await client.set("mykey", "10");
    const value1 = await client.incr("mykey");
    console.log(value1); // 11
    ```
    
7. **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
        
    
    ```bash
    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
        
    
    ```javascript
    await client.set("mykey", "10");
    const value1 = await client.decr("mykey");
    console.log(value1); // 9
    ```
    
8. **LPUSH**
    
    > Add element to the start of a list
    
    Example
    
    * CLI
        
    
    ```bash
    LPUSH mylist "world"
    (integer) 1
    
    LPUSH mylist "hello"
    (integer) 2
    
    LRANGE mylist 0 -1
    1) "hello"
    2) "world"
    ```
    
    * Node.js
        
    
    ```javascript
    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' ]
    ```
    
9. **RPUSH**
    
    > Add element to the end of a list
    
    Example
    
    * CLI
        
    
    ```bash
    RPUSH mylist "hello"
    (integer) 1
    
    RPUSH mylist "world"
    (integer) 2
    
    LRANGE mylist 0 -1
    1) "hello"
    2) "world"
    ```
    
    * Node.js
        
    
    ```javascript
    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' ]
    ```
    
10. **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 asynchronously
        
    * `SYNC`: flushes the databases synchronously
        
    
    Example
    
    * CLI
        
    
    ```bash
    FLUSHALL SYNC
    ```
    
    * Node.js
        
    
    ```javascript
    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](https://redis.io/docs/latest/commands/).

---

# 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.

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1749555959469/88f8f284-2998-4c7a-acab-b840be4e1bd8.png align="center")

## 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](https://linktr.ee/debangshu919) if you'd like to see more in-depth tutorials on specific Redis features.

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1749560904236/425da684-e8fc-4eaf-aa71-b5f782791c0a.jpeg align="center")
