Caching in JavaScript: Redis, Memcached, and Built-in Solutions (Advanced Level)

Online Python Trainer for Beginners

Learn Python easily without overwhelming theory. Solve practical tasks with automatic checking, get hints in Russian, and write code directly in your browser — no installation required.

Start Course

Caching in JavaScript: Redis, Memcached, and Built-in Solutions (Advanced Level)



In modern web development, application performance often hinges on data access speed. Every extra query to a database or external API increases response time and server load. Caching is not just about "saving a result" — it's a whole science involving choosing the right strategy, tool, and invalidation mechanism. In this article, we will explore advanced caching techniques in Node.js: from built-in solutions to industrial-grade systems like Redis and Memcached.



1. Built-in Caching in Node.js: Simplicity and Limitations



Before integrating external services, it's worth evaluating the capabilities of Node.js itself. Built-in caching is implemented using Map or WeakMap objects, as well as simple global variables. This is ideal for data that rarely changes and lives within a single process.



// Simple in-memory cache with TTL (Time To Live)class MemoryCache {  constructor(ttl = 60000) {    this.cache = new Map();    this.ttl = ttl;  }

set(key, value) { this.cache.set(key, { value, expiry: Date.now() + this.ttl }); }

get(key) { const item = this.cache.get(key); if (!item) return null; if (Date.now() > item.expiry) { this.cache.delete(key); return null; } return item.value; }

delete(key) { this.cache.delete(key); }

clear() { this.cache.clear(); }}

// Usageconst cache = new MemoryCache(30000); // 30 seconds TTLcache.set('user:42', { name: 'Alice', role: 'admin' });console.log(cache.get('user:42')); // { name: 'Alice', role: 'admin' }


Pros: zero network latency, simple implementation, no external dependencies required.
Cons: data is lost on process restart, does not scale across multiple servers, limited by the RAM of a single node.



For microservices running in a single process, or for caching the results of heavy computations (e.g., template rendering), a built-in solution is an excellent choice. However, it is insufficient for distributed systems.



2. Redis: The King of Caching in Node.js



Redis is an in-memory data store often used as a high-performance cache. Its main advantages include support for complex data structures (strings, lists, sets, hashes), built-in TTL, pub/sub, and disk persistence.



Connecting Redis in Node.js



To work with Redis in Node.js, the ioredis package (recommended) or redis package is used. Let's look at an example with ioredis:



const Redis = require('ioredis');

const redis = new Redis({ host: 'localhost', port: 6379, retryStrategy: (times) => Math.min(times * 50, 2000) // reconnection strategy});

// Basic operationsawait redis.set('mykey', 'Hello, Redis!', 'EX', 60); // TTL 60 secondsconst value = await redis.get('mykey');console.log(value); // "Hello, Redis!"

// Using a hash to store complex objectsawait redis.hmset('user:100', { name: 'Bob', email: 'bob@example.com', age: 30});const user = await redis.hgetall('user:100');console.log(user); // { name: 'Bob', email: 'bob@example.com', age: '30' }


Advanced Strategies with Redis



Cache-Aside (Lazy Loading): The application first checks the cache, and only on a miss does it query the database and populate the cache.



async function getUser(userId) {  const cacheKey = `user:${userId}`;  let user = await redis.get(cacheKey);  if (user) {    return JSON.parse(user);  }  // Cache miss — load from DB  user = await db.findUserById(userId);  if (user) {    await redis.set(cacheKey, JSON.stringify(user), 'EX', 3600); // cache for 1 hour  }  ret                

Blogs

Book Recommendations