Caching in JavaScript: Redis, Memcached, and Built-in Solutions
Caching is one of the key strategies for optimizing web application performance. In the JavaScript ecosystem (especially Node.js), developers have access to powerful tools: from built-in mechanisms to distributed systems like Redis and Memcached. In this article, we will break down how and when to use each approach, with real code examples.
Why is caching needed in Node.js?
Without caching, each request to the server can lead to expensive operations: reading from the database, complex computations, or calls to external APIs. The cache stores the result of the first request and serves it on subsequent requests. This reduces server load, decreases response time, and improves user experience.
Main use cases for caching in Node.js:
- Database query results (especially aggregations)
- External API responses (weather, exchange rates)
- Heavy computations (report generation, image processing)
- User sessions and authentication tokens
Built-in caching in JavaScript (Node.js)
The simplest way is to use a Map or Object to store data in the process memory. This is fast, but has limitations: data only lives while the server is running, and memory is not unlimited.
Example: Map-based cache with TTL (Time To Live)
class SimpleCache { constructor(ttl = 60000) { this.cache = new Map(); this.ttl = ttl; // time to live in ms (default 1 minute) }
set(key, value) { this.cache.set(key, { value, timestamp: Date.now() }); }
get(key) { const item = this.cache.get(key); if (!item) return null; if (Date.now() - item.timestamp > this.ttl) { this.cache.delete(key); return null; } return item.value; }
delete(key) { this.cache.delete(key); }
clear() { this.cache.clear(); }}
// Usageconst cache = new SimpleCache(30000); // 30 secondscache.set('user_123', { name: 'Ivan', role: 'admin' });const user = cache.get('user_123');console.log(user); // { name: 'Ivan', role: 'admin' }Pros: zero latency, simplicity, no external dependencies required.
Cons: data is lost on restart, limited by single process memory, not suitable for distributed systems.
For a more advanced built-in cache, you can use the node-cache package, which adds automatic cleanup, statistics, and support for string keys.
Redis: distributed cache for Node.js
Redis is an in-memory data store that is often used as a cache. In Node.js, the ioredis package (more modern than redis) is used to work with Redis.
Installation and basic connection
npm install ioredisconst Redis = require('ioredis');const redis = new Redis({ host: 'localhost', port: 6379, // password: 'your-password' // if required});
redis.on('connect', () => console.log('Connected to Redis'));redis.on('error', (err) => console.error('Redis error:', err));Example: Caching data with TTL
const Redis = require('ioredis');const redis = new Redis();
async function getCachedData(key, fetchFunction, ttl = 3600) { // Try to get from cache const cached = await redis.get(key); if (cached) { return JSON.parse(cached); }
// If not found — get data and save it const data = await fetchFunction(); await redis.setex(key, ttl, JSON.stringify(data)); return data;}
// Usage example: caching