In-memory Cache for Node.js
node-cache is a simple, fast, and internal in-memory caching module for Node.js applications, designed to function similarly to memcached but within a single Node.js process. It supports setting key-value pairs with optional time-to-live (TTL) expiration, allowing for automatic invalidation and deletion of stale data. The current stable version is 5.1.2, actively maintained with regular updates addressing bug fixes and minor features, as evidenced by recent 5.x releases. A major breaking change in v5.0.0 removed callback support, shifting entirely to synchronous operations (with an opt-in legacy callback option for migration), and dropped the `lodash` dependency, improving performance and reducing the bundle size. It differentiates itself by its straightforward API and focus on local process caching, suitable for scenarios where a full-fledged external caching solution like Redis or Memcached is overkill. Keys can be strings or numbers, and the cache can be configured with standard TTLs, periodic cleanup, and an option to store references vs. clones of values, balancing performance and data isolation.
Common errors
-
TypeError: myCache.get is not a function (when using callbacks after v5)
cause Attempting to use callback-based API (`myCache.get(key, callback)`) after upgrading to v5.x, where callbacks were removed by default.fixRemove the callback argument and use the synchronous return value: `const value = myCache.get(key);` -
Error: Key type 'object' is not supported. Use 'string' or 'number'.
cause Trying to use an object (or other non-string/non-number type) as a cache key.fixConvert your key to a string (e.g., `JSON.stringify(myObjectKey)` or `myObjectKey.id.toString()`) or ensure it's a number before passing it to cache methods. -
Cache is full, cannot add new key (when maxKeys is set)
cause Attempting to add a new item to the cache when the `maxKeys` limit has been reached.fixIncrease the `maxKeys` option during initialization (`new NodeCache({ maxKeys: desiredLimit })`), implement a custom eviction strategy by manually deleting less important keys, or handle the error gracefully. -
Values were still being deleted after expiration even with 'deleteOnExpire: false' (pre-v5.0.2)
cause A bug in versions prior to 5.0.2 caused expired values to be deleted regardless of the `deleteOnExpire` setting.fixUpgrade to `node-cache` version 5.0.2 or newer to ensure `deleteOnExpire: false` functions as intended, allowing you to handle expired items manually via the 'expired' event.
Warnings
- breaking Version 5.0.0 completely removed support for callback-based API methods. All operations are now synchronous. If you rely on callbacks, you must migrate to synchronous calls or temporarily enable legacy callbacks.
- breaking Node.js versions prior to 8.x are no longer supported since v5.x. Running on older Node.js environments will lead to compatibility issues or errors.
- breaking In version 4.0.0, the behavior of `.ttl(key, 0)` and `stdTTL=0` was fixed. Previously, setting TTL to 0 would immediately delete the key. It now correctly sets an unlimited TTL.
- gotcha The `useClones` option (default: `true`) determines if stored values are deep-cloned. If `true`, you get a copy, preventing external mutations from affecting cached data. If `false`, you get a reference, which is faster but means cached objects can be mutated externally, potentially leading to unexpected behavior.
- gotcha Keys must be `string` or `number` types since v4.1.0. Other types will throw an error during `set` operations.
- deprecated The `enableLegacyCallbacks` option, which re-enables callback support for compatibility with pre-v5 APIs, is marked for removal in v6.x.
Install
-
npm install node-cache -
yarn add node-cache -
pnpm add node-cache
Imports
- NodeCache
const NodeCache = require('node-cache');import NodeCache from 'node-cache';
- NodeCache
import { NodeCache } from 'node-cache';const NodeCache = require('node-cache'); - NodeCacheEvents
import { NodeCacheEvents } from 'node-cache'; // Usage: myCache.on(NodeCacheEvents.EXPIRED, ...)
Quickstart
import NodeCache from 'node-cache';
const myCache = new NodeCache({ stdTTL: 60, checkperiod: 120, useClones: false });
myCache.set('myKey', 'myValue', 10); // Cache for 10 seconds
let value = myCache.get('myKey');
if (value) {
console.log(`Retrieved: ${value}`);
} else {
console.log('Key not found or expired.');
}
// Simulate an async operation and cache its result
async function fetchDataAndCache(key) {
let cachedData = myCache.get(key);
if (cachedData) {
return cachedData;
}
console.log('Fetching fresh data...');
const freshData = await new Promise(resolve => setTimeout(() => resolve({ id: 1, name: 'Fresh Data' }), 500));
myCache.set(key, freshData, 30);
return freshData;
}
fetchDataAndCache('asyncData').then(data => console.log('Async data:', data));
// Get and delete a key with a single operation (v5.1.0+)
const takenValue = myCache.take('myKey');
console.log(`Taken value: ${takenValue}`);
console.log(`Is myKey still in cache? ${myCache.has('myKey')}`);