BairesDev
  1. Blog
  2. Software Development
  3. Caching Node JS: Boosting Performance & Efficiency
Software Development

Caching Node JS: Boosting Performance & Efficiency

Boost your Node JS performance with caching techniques! Learn how to implement caching in your projects and improve your app's speed.

BairesDev Editorial Team

By BairesDev Editorial Team

BairesDev is an award-winning nearshore software outsourcing company. Our 4,000+ engineers and specialists are well-versed in 100s of technologies.

17 min read

Featured image

Are you tired of slow and resource-intensive database queries in your Node.js application? You can get rid of these issues and improve performance by caching the node js application. Caching is an important technique in software development that has been used to improve application performance, leading to an efficient data retrieval process by providing an intermediary storage mechanism. It involves storing frequently accessed data and objects in a temporary storage area, so they can quickly get the retrieved data when needed.

This article will cover the basics of caching, an overview of the Redis server, the implementation of caching in Redis, and the different solutions available in the market. By the end of this article, you will better understand the scenarios where caching is useful, what to cache, and the appropriate techniques to implement caching in your Node.js applications based on your specific use case.

What Is Node.js?

Node.js is an open-source server-side JavaScript runtime environment built on Google Chrome’s V8 JavaScript engine, which allows developers to write server-side code using JavaScript syntax rather than another language like Java or Python. It makes life easier for frontend developers familiar with client-side programming by enabling them to work on backend code as well as vice versa allowing backend developers who are more comfortable working on serverside tasks such as databases or APIs access to the same languages and libraries readily available for web browsers meaning less time spent learning new technologies just because you switched between client-side/server-side coding.

This makes NodeJS highly popular among modern web application frameworks since its introduction in 2009 by Ryan Dahl due largely in part due the fact that it utilizes non-blocking asynchronous I/O operations, which allow programs written in Node.js much better resource utilization characteristics than traditional synchronous methods where all requests must wait until one request is completed.

Why Cache Data in the First Place?

Caching data is a common practice for an efficient data retrieval process. Cached data reduces latency when accessing large datasets. By keeping recently requested items close at hand, retrieval times are faster than if they had to be retrieved from their source each time a request was made. Additionally, this allows for more efficient use of resources since multiple requests for similar requested data can be handled with just one lookup rather than making separate requests each time.

For example, if an application needs weather forecast information every hour, caching this data would save time because new forecasts wouldn’t need to be downloaded repeatedly throughout the day. Instead, they could retrieve data at the beginning of each hour using cached data stored in memory.

Another benefit of caching is improved scalability since fewer remote calls have to be made, which reduces server load and extends capacity allowing more users access without slowing down response times due to too much strain on system resources as it leads to cache frequently queried data. It also ensures that when traffic spikes occur due to increased demand, there will still be sufficient levels of service available as the cache stores high-frequency queries locally, thus avoiding slowdowns associated with outages from remote sources like APIs or databases that may not have been designed expecting large numbers concurrent calls being made all at once.

Caching also enhances security as it prevents sensitive user information such as passwords or credit card details from being exposed over open networks where unauthorized parties may intercept them before reaching their intended target – another added layer of protection potentially preventing malicious attacks on systems hosting sensitive customer records making sure only those authorized to get access what’s inside

Cached data can provide cost savings since numerous storing data and fetching data operations do not have to happen, resulting in lower resource usage while maintaining the same level of service quality expected by customers who expect fast and responsive experiences regardless of how many people are using a given product or service.

Types of Caching

There are several types of caching that can be used in various contexts, including client-side caching, server-side caching, and content delivery networks (CDNs). Each type of caching has benefits and is suited to different use cases, so it’s important to understand their differences to choose the right caching strategy for your particular needs.

Type of Caching Definition Examples
Client-Side Caching Caching of web pages and resources on the user’s computer. Browser caching of images, CSS, and JavaScript
Server-Side Caching Storing website or application components on an external server. Memcached, Redis, and LevelDB
Content Delivery Networks (CDNs) Large distributed systems delivering cached static content. Cloudflare, Akamai, and Amazon CloudFront

The table outlines the benefits and drawbacks of each caching type in terms of factors such as capacity, availability, scalability, and implementation complexity. Ultimately, the choice of caching strategy will depend on the specific needs and requirements of a given project or application.

When To Use Redis for Caching?

Redis caching is a type of database storage that provides high-speed access to data stored in memory. Redis caches are an excellent choice for applications where large data must be retrieved and stored quickly. This makes them particularly suitable for web-based applications, such as those used by eCommerce websites or content management systems (CMS).

When deciding whether to use Redis caching, it is important to consider the size and complexity of your application. For example, if you have a small website with only minimal traffic, there may not be any need for Redis caching since its benefits may not outweigh the cost involved in setting up the system. However, using Redis can make sense if you have a larger website with regular visitors or customers who require fast response times from your server.

Another factor when considering whether to use Redis caching is how often data needs to be accessed and updated on the server side making data access operations quicker. If data changes frequently, then using Redis could provide improved performance compared with other methods, such as disk based database due to its ability to handle multiple requests simultaneously without slowing down significantly. It also allows developers more control over how updates are handled to ensure that new information is distributed across all connected clients quickly and reliably rather than waiting until each request has been processed before updating it on all servers simultaneously, which can take longer depending on network latency etc.

In addition, another key benefit offered by using Redis caching is scalability; this means that should your site experience sudden increases in user base or activity levels, then expanding capacity via additional nodes becomes much simpler than having a traditional database setup done manually which takes time and resources away from other aspects such as creating new features/functionality for users, etc.

Since the cached versions of objects remain stored within RAM, page load times will generally decrease along with increased throughput due again reduced latency associated when retrieving information directly from disk drives versus memory locations where everything happens almost instantaneously, thus leading to further improvements in overall responsiveness seen by end users making their interactions smoother & faster which helps create better experiences overall no matter what device they’re viewing things through – mobile phones tablets laptops desktops, etc

Implement Caching in Node JS

Let’s say we have an e-commerce website displaying a list of users. Each time the url is accessed, the application queries the database to fetch the latest users, which can be slow and resource-intensive. We can use Redis caching to store the database query results and serve them directly from the cache for subsequent requests.

Here’s how you can implement Redis caching in a Node.js application:

Pre-Requisites

  • Redis: Redis is an in-memory data structure store that can be used as a database, cache, and message broker.
  • Node.js: Node.js is an open-source, cross-platform JavaScript runtime environment that enables developers to build server-side applications using JavaScript.
  • Redis client for Node.js: To use Redis in Node.js, you must install a Redis client library such as “redis” through npm.
  • Basic knowledge of Redis commands: Before you can run caching with Redis, you need to have a basic understanding of Redis commands such as SET, GET, and EXPIRE, which are used to store, retrieve, and expire data respectively.

Step 1: Install Redis Server

You can download the installer using the official Redis website. Follow the instructions for your operating system to install Redis.

Alternatively, you can use a package manager to install Redis. For example, on Ubuntu or Debian Linux, you can use the following command:

sudo apt-get install redis-server

On macOS, you can use Homebrew to install Redis:

brew install redis

On Linux, after installing Redis, you can start the Redis server by running the following command in a terminal:

redis-server

On macOS, you can start the Redis server by running the following command in a terminal:

redis-server /usr/local/etc/redis.conf

On windows, after installation from the website, you can start the Redis server by running the following command in a Command Prompt window:

redis-server.exe

This starts Redis with default configuration settings.

Step 2: Create a New Node.js Project

  • Create a new directory for your project and navigate to it in your terminal.
  • Run the following command to create a new package.json file:
npm init -y

Your package.json file should look something like this:

{
  "name": "redis-nodejs",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
}

Step 3: Install the Required Dependencies

Next, you will need to install the following packages:

  • express: a web server framework for Node.js.
  • node-redis: a Redis client that allows you to store and access data in Redis.

Install the Express web framework and the Redis client for Node.js using the following command:

npm install express redis axios

Your package.json file should look something like this after the installation of the necessary packages:

{
  "name": "redis-nodejs",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "dependencies": {
    "axios": "^1.3.4",
    "express": "^4.18.2",
    "redis": "^4.6.5"
  }
}

Step 4: Set Up a Redis Client in Your Node.js Application

In your Node.js application, create a new file named server.js and add the following code to it:

const express = require('express'); 
const redis = require('redis'); 

const { createClient } = require('redis'); 

const app = express(); 
const port = process.env.PORT || 3000;

In the above code snippet, you import the required modules to set up an Express server and Redis client in Node.js.

Next, create an instance of the Express app using const app = express() and set the port variable to either the value of the environment variable defined in the .env file or 3000 if it’s not defined.

You are now ready to start building your caching system using Redis and Express.

This code sets up a Redis client using the Node.js Redis library and connects to a Redis server.

Step 5: Create a Redis Client and Connect to a Redis Server

Now add the following code into the server.js file:

let redisClient;

(async () => {
  redisClient = createClient();

  redisClient.on("error", (error) => console.error(`Error : ${error}`));

  await redisClient.connect();
})();

The first line declares a variable called redisClient, which will store the Redis client object.

The code then defines an immediately invoked function expression (IIFE) using the async/await syntax, which does the following:

  1. Creates a Redis client using the createClient() function. This function is provided by the Node.js Redis library and creates a new Redis client object that can be used to interact with a Redis server.
  2. Registers an error handler on the Redis client object, which logs any errors to the console.
  3. Calls the connect() method on the Redis client object using await, which establishes a connection to the Redis server. This method returns a Promise, which is why it needs to be awaited.

Step 6: Fetch Data From an External API

Now add the following function to fetch data from API.

async function fetchApiData() {
    const apiResponse = await axios.get(
      `https://jsonplaceholder.typicode.com/users`
    );
    console.log("Request sent to the API");
    return apiResponse.data;
  }

Step 7: Caching Node JS Server Requests

Add the following function getUsersData, which first extracts the users parameter from the request object using req.params.users. It then declares two variables results and isCached, initializing the latter to false as there would be no cache initially.

async function getUsersData(req, res) {
    const users = req.params.users;
    let results;
    let isCached = false;
    
    try {
        const cacheResults = await redisClient.get(users);
        if (cacheResults) {
            isCached = true;
            results = JSON.parse(cacheResults);
        } else {
            results = await fetchApiData();
        if (results.length === 0) {
            throw "API returned an empty array";
        }
            await redisClient.set(users, JSON.stringify(results));
        }
    
        res.send({
            fromCache: isCached,
            data: results,
        });
    } catch (error) {
        console.error(error);
        res.status(404).send("Data unavailable");
    }
}

Next, the function attempts to retrieve cached results from a Redis database using redisClient.get(users) function call. If cached results exist, the isCached variable is set to true, and the cached results are parsed from a JSON string using JSON.parse(cacheResults).

If no cached results are found, the function calls another asynchronous function fetchApiData(), to obtain results. If fetchApiData() returns an empty array, an exception is thrown with the message “API returned an empty array”.

If fetchApiData() returns non-empty results, the function stores the results as a JSON string in the Redis cache using redisClient.set(users, JSON.stringify(results)).

Finally, the function sends a response to the client with an object containing the isCached variable and results data, using res.send({ fromCache: isCached, data: results }). If an exception is caught during the execution of the try block, the function logs an error to the console and sends a 404 response with the message “Data unavailable” using res.status(404).send(“Data unavailable”).

Step 8: Configure App Routes

Add the following routes to the app.

app.get("/users/:users", getUsersData);

app.listen(port, () => {
  console.log(`App listening on port ${port}`);
});

The consolidated server.js file should look something like this.

const express = require('express');
const redis = require('redis');
const { createClient } = require('redis');

const app = express();
const port = process.env.PORT || 3000;

let redisClient;

(async () => {
  redisClient = createClient();

  redisClient.on("error", (error) => console.error(`Error : ${error}`));

  await redisClient.connect();
})();

async function fetchApiData() {
    const apiResponse = await axios.get(
      `https://jsonplaceholder.typicode.com/users`
    );
    console.log("Request sent to the API");
    return apiResponse.data;
  }
  
async function getUsersData(req, res) {
    const users = req.params.users;
    let results;
    let isCached = false;
    
    try {
        const cacheResults = await redisClient.get(users);
        if (cacheResults) {
            isCached = true;
            results = JSON.parse(cacheResults);
        } else {
            results = await fetchApiData();
        if (results.length === 0) {
            throw "API returned an empty array";
        }
            await redisClient.set(users, JSON.stringify(results));
        }
    
        res.send({
            fromCache: isCached,
            data: results,
        });
    } catch (error) {
        console.error(error);
        res.status(404).send("Data unavailable");
    }
    }
    
app.get("/users/:users", getUsersData);

app.listen(port, () => {
  console.log(`App listening on port ${port}`);
});

Step 9: Start the Server and Test Redis Caching

Start the server by running the following command in your terminal:

node server.js

Step 10: Accessing Retrieved Data

You will have to visit http://localhost:3000/users/all/ to see the requested data. The server will fetch data.

Reload the page a few times. You can now see that the requested data shows fromCache to be true. This means you see the cache data.

That’s it! With these steps, you should now have a basic implementation of caching using Redis with Node.js in your e-commerce application.

Alternatives

Redis is a popular and powerful in-memory data structure store. It has become increasingly popular as an alternative to traditional database systems due to its scalability, high performance, and flexibility. Redis may not always be the best solution for every application or particular use case. Several alternatives to Redis in Node.js exist, each with features, advantages, and limitations. Here are some of the most popular alternatives to Redis:

Memcached

Memcached is a high-performance, distributed memory object caching system. It is designed to cache frequently accessed data in memory to reduce the times an application must fetch data from a database or other source. Memcached is often used for large-scale web applications that require high-speed same data access.

One of the advantages of Memcached over Redis is its simplicity. It is easy to use and has a small memory footprint, making it ideal for smaller projects or applications with limited resources. However, Memcached does not offer some of the more advanced features of Redis, such as persistence or advanced data types.

MongoDB

MongoDB is a popular NoSQL database that can be used as an alternative to Redis. MongoDB is designed to store and manage large amounts of unstructured data, making it a good choice for applications requiring data storage flexibility.

One of the advantages of MongoDB over Redis is its scalability. MongoDB can handle large amounts of data and is designed to scale horizontally across multiple servers. It also offers more advanced querying capabilities than Redis, making it a better choice for complex data retrieval applications.

Apache Cassandra

Apache Cassandra is a highly scalable NoSQL database that can be used as an alternative to Redis. Cassandra is designed to handle large amounts of data across multiple servers and can provide high availability and fault tolerance.

One of the advantages of Cassandra over Redis is its scalability. Cassandra can handle large amounts of data and is designed to scale horizontally across multiple servers. It also offers more advanced querying capabilities than Redis, making it a better choice for complex data retrieval applications.

LevelDB

LevelDB is an open-source key-value store that can be used as an alternative to Redis. LevelDB is designed to be lightweight and fast, making it a good choice for smaller projects or applications with limited resources.

One of the advantages of LevelDB over Redis is its simplicity. It is easy to use and has a small memory footprint, making it ideal for smaller projects or applications with limited resources. However, LevelDB does not offer some of the more advanced features of Redis, such as persistence or advanced data types.

In conclusion, the choice of an alternative to Redis in Node.js will depend on the specific requirements of your project, such as the size of the data, scalability, and querying capabilities needed. Each alternative has its own set of features and limitations, and it is essential to evaluate them based on your specific project needs.

Conclusion

In conclusion, caching with Redis is an excellent way to optimize data access operations in Node.js applications. With the ability to store data and retrieve data quickly, caching can greatly improve application performance and user experience. Additionally, Redis offers several useful features such as replication, clustering, transactions, pub/sub messaging, and more which can help developers build advanced architectures for distributed systems.

It also provides high-availability solutions allowing you to deploy your application across multiple servers or cloud providers without worrying about downtime or latency issues due to network failures or other system problems. All these advantages make Redis one of the most popular choices for caching in Node.js applications today.

If you’re looking for Node.js development services, BairesDev is a top Node.js development company that can help you build scalable, high-performance applications using the latest technologies and best practices. If you’re looking to hire Node.js developers, BairesDev has a comprehensive hiring guide to help you find the right talent for your project. And when it comes to ensuring the security of your Node.js applications, BairesDev’s Node.js security best practices can help you protect your data and users. Contact BairesDev today to learn more about our Node.js services and how we can help you build better applications.

If you enjoyed this article, check out our other guides below;

Key Questions

How to use cache in Node JS?
To use cache in Node.js, you can use in-memory caching, client-side caching, or distributed caching solutions like Redis.

Is Redis good for cache?
Redis is a popular choice for cache in Node.js due to its speed, scalability, and support for advanced data structures.

When should you not use Redis?
You may not want to use Redis if you have very simple caching needs or if you need strong data consistency guarantees.

Does Netflix use Redis?
Netflix uses Redis for various purposes, including session management and content discovery.

Tags:
BairesDev Editorial Team

By BairesDev Editorial Team

Founded in 2009, BairesDev is the leading nearshore technology solutions company, with 4,000+ professionals in more than 50 countries, representing the top 1% of tech talent. The company's goal is to create lasting value throughout the entire digital transformation journey.

Stay up to dateBusiness, technology, and innovation insights.Written by experts. Delivered weekly.

Related articles

Software Development - The Power of
Software Development

By BairesDev Editorial Team

18 min read

Contact BairesDev
By continuing to use this site, you agree to our cookie policy and privacy policy.