Caching Next.js API routes with Redis

Photo

Here is the time difference we observed after caching the API routes with Redis.

So I recently started to observe the response time of api.crackeddevs.com (opens in a new tab) started to increase due to lot of traffic and huge amount of data being fetched from the database.

So I decided to cache the API routes with Redis.

What is Redis?

Redis is an open source in-memory data structure store which uses Key-Value pair to store data. And its blazingly fast.

So now the question was which Redis provider to use and we came to conclusion with two options:

So with some discussion and a suggestion from my friend Yashwanth (opens in a new tab) we decided to go with Upstash's Redis.

We used Upstash JS SDK to connect to the Redis instance and store the data in the cache.

Installation

 
npm i @upstash/redis
 

Importing the Redis SDK

 
import { Redis } from "@upstash/redis";
 

Initialization Redis Object

 
const redis = new Redis({
  url: `${process.env.UPSTASH_REDIS_REST_URL}`,
  token: `${process.env.UPSTASH_REDIS_REST_TOKEN}`,
});
 

It needs two environment variables UPSTASH_REDIS_REST_URL and UPSTASH_REDIS_REST_TOKEN which can be found in the Upstash dashboard.

Creating Redis Key

const RedisKey = `jobs:.....\n`;  // unique key

Adding a response to Redis with expiry time

await redis.set(RedisKey, JSON.stringify(data)); // stores the object as string
await redis.expire(RedisKey, 600);   // 10 minutes

Retrieving the data from Redis

 
const CachedData = await redis.get(jobRedisKey);
 

Conditional to check if cache exists , if yes then return cache

 
  if (CachedData) {
      // If data is found in cache, parse it if it's a string and return
      console.log('cache HIT');
      const data =
        typeof CachedData === 'string' // checks if the data is string if yes then parse it
          ? JSON.parse(CachedData)
          : CachedData;
 
      return NextResponse.json(data); // return the cached data
    }
 

So the final code looks like this

 
import { NextResponse } from 'next/server';
import { Redis } from '@upstash/redis';
 
const redis = new Redis({
  url: `${process.env.UPSTASH_REDIS_REST_URL}`,
  token: `${process.env.UPSTASH_REDIS_REST_TOKEN}`,
});
 
const RedisKey = `jobs:.....\n`; // unique key
 
export default async function handler(req, res) {
  const CachedData = await redis.get(jobRedisKey);
 
  if (CachedData) {
    // If data is found in cache, parse it if it's a string and return
    console.log('cache HIT');
    const data =
      typeof CachedData === 'string' // checks if the data is string if yes then parse it
        ? JSON.parse(CachedData)
        : CachedData;
 
    return NextResponse.json(data); // return the cached data
  }
 
  const response = await fetch('https://jobs.github.com/positions.json?description=javascript&location=remote'); // fetching example but can be anything
 
  const data = await response.json();
 
  await redis.set(RedisKey, JSON.stringify(data)); // stores the object as string
  await redis.expire(RedisKey, 600); // 10 minutes
 
  return NextResponse.json(data);
}
 

At last

So that's it , I hope you enjoyed reading this article , if you did please share it on twitter (opens in a new tab)

also visit crackeddevs.com (opens in a new tab)

Have a great day ahead . ☀️

© anurag.RSS