🚀 Supercharge Your Node.js App with Caching: A Developer’s Guide with Code Examples

KUNTAL MAITYKUNTAL MAITY
5 min read

📌 Introduction

Performance is key when building scalable Node.js applications. But with growing traffic and complex logic, response times can take a hit—especially when your app makes repeated database or API calls.

This is where caching steps in—it helps you avoid redundant processing by storing and serving frequently accessed data efficiently.

In this blog, you'll learn about different caching mechanisms in Node.js, when to use them, and how to implement each with real code examples. Whether you're building a blog, e-commerce site, or an API server—this guide will help you supercharge your app's performance.


⚙️ What is Caching?

Caching is the process of storing copies of data in a temporary storage (cache), so it can be accessed faster next time it’s requested. Instead of recalculating or re-fetching data from a database or API, your application returns it directly from cache—saving time and resources.


🧰 Caching Mechanisms in Node.js (with Code)


🔹 1. In-Memory Caching with node-cache

A simple, fast, and efficient way to cache data in memory. Best suited for small apps or single-instance services.

✅ When to use:

  • Caching API responses
  • Preventing duplicate DB calls
  • Frequently accessed data

🧪 Code Example:

npm install node-cache
// cache.js
import NodeCache from "node-cache";
const cache = new NodeCache({ stdTTL: 100 }); // TTL = 100 seconds
export default cache;
// server.js
import express from "express";
import cache from "./cache.js";

const app = express();

app.get("/data", async (req, res) => {
  const cachedData = cache.get("myData");
  if (cachedData) {
    return res.json({ fromCache: true, data: cachedData });
  }

  const fetchedData = await fakeDBCall();
  cache.set("myData", fetchedData);
  res.json({ fromCache: false, data: fetchedData });
});

const fakeDBCall = async () => {
  return new Promise((resolve) => {
    setTimeout(() => resolve({ value: "Fresh Data" }), 1000);
  });
};

app.listen(3000, () => console.log("Server running on port 3000"));

Read the full documentation of node-cache here.


🔹 2. Distributed Caching with Redis

Redis is a blazing-fast in-memory data store that works across multiple servers—making it perfect for scalable applications.

✅ When to use:

  • Shared cache in microservices
  • Session storage
  • Expensive DB queries

🧪 Code Example:

npm install redis
// redisClient.js
import { createClient } from "redis";
const client = createClient();
client.on("error", (err) => console.error("Redis error:", err));
await client.connect();
export default client;
// server.js
import express from "express";
import redisClient from "./redisClient.js";

const app = express();

app.get("/products", async (req, res) => {
  const cached = await redisClient.get("products");
  if (cached) {
    return res.json({ fromCache: true, data: JSON.parse(cached) });
  }

  const data = await fetchProducts();
  await redisClient.setEx("products", 3600, JSON.stringify(data));
  res.json({ fromCache: false, data });
});

const fetchProducts = async () => {
  return [{ id: 1, name: "Laptop" }, { id: 2, name: "Phone" }];
};

app.listen(3000, () => console.log("Server running on port 3000"));

Read the full documentation of redis here.


🔹 3. HTTP-Level Caching with Headers

You can set HTTP headers to instruct the browser or proxy servers to cache certain content for a specific period.

✅ When to use:

  • Static files (images, CSS, JS)
  • Public API responses

🧪 Code Example:

// Static file caching
app.use(express.static("public", {
  maxAge: "1d" // Cache for 1 day
}));

// API route caching
app.get("/public-api", (req, res) => {
  res.set("Cache-Control", "public, max-age=600"); // Cache for 10 minutes
  res.json({ message: "This is public data" });
});

🔹 4. Query-Level Caching in Code

Manually store results of frequent or expensive database queries using in-memory objects or cache libraries.

✅ When to use:

  • Reports
  • Analytics
  • Top listings

🧪 Code Example:

let queryCache = {};

app.get("/top-users", async (req, res) => {
  if (queryCache.topUsers) {
    return res.json({ fromCache: true, data: queryCache.topUsers });
  }

  const users = await User.find().sort({ score: -1 }).limit(10);
  queryCache.topUsers = users;

  setTimeout(() => delete queryCache.topUsers, 10 * 60 * 1000); // Expire in 10 mins
  res.json({ fromCache: false, data: users });
});

🔹 5. Route-Level Caching with apicache

A simple middleware to cache entire route responses. Perfect for routes that serve expensive or rarely updated data.

✅ When to use:

  • Dashboard stats
  • Reports
  • Public content

🧪 Code Example:

npm install apicache
import apicache from "apicache";
const cache = apicache.middleware;

app.get("/stats", cache("5 minutes"), async (req, res) => {
  const stats = await getStatsFromDB();
  res.json(stats);
});

🔹 6. CDN Caching (Bonus!)

For static websites or frontend-heavy apps, CDNs like Cloudflare, Vercel, or Netlify cache your content globally, reducing load times drastically.

✅ When to use:

  • Images, fonts, videos
  • Static pages (marketing sites)
  • Frontend bundles (Next.js, React, etc.)

👉 No code required—just set proper caching headers and let the CDN handle the rest!


📏 Best Practices for Caching

✅ Tip📌 Description
Use TTLAlways set expiration (TTL) to avoid stale data
Cache selectivelyDon’t cache everything—only what’s worth it
Smart invalidationClear cache when DB is updated
Monitor performanceTrack cache hit/miss ratios
Avoid over-cachingToo much caching can cause consistency issues

🧠 Conclusion

Caching is one of the most effective ways to improve your Node.js app’s performance—reducing response time, database load, and overall latency.

From simple in-memory caches to powerful distributed caching with Redis, choosing the right caching strategy can make your application faster and more scalable.

🎯 Start small. Pick one route or DB query to cache and gradually expand caching across your application.


💬 Have Questions or Suggestions?

Drop a comment below or connect with me on LinkedIn or GitHub. Let’s make apps faster together! 🚀

0
Subscribe to my newsletter

Read articles from KUNTAL MAITY directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

KUNTAL MAITY
KUNTAL MAITY

I’m a passionate Full-Stack Developer who loves building performance-driven web and mobile applications. I work primarily with JavaScript, React, Next.js, Node.js, and MongoDB, and I enjoy simplifying complex concepts into developer-friendly tutorials. On this blog, you'll find hands-on guides, real-world projects, and developer insights—all aimed at helping you level up your coding skills and build production-ready apps. Whether you're into backend performance, frontend polish, or full-stack architecture, there's something here for you! Let’s learn, build, and grow together. 💻✨