A simple, fast, in-memory caching module for Node.js with set, get, and delete methods. Works like memcached but runs entirely in-process. Keys support automatic expiration via TTL.
This is an actively maintained fork of the original node-cache by @mpneuried. The original project is no longer maintained. This fork continues development with bug fixes, a full TypeScript rewrite, and performance improvements while keeping the public API fully backward-compatible.
This fork (v6.0.0) includes the following improvements over the last published original (v5.1.2):
- TypeScript rewrite -- Full rewrite from CoffeeScript to TypeScript. Type definitions are now generated from source, not hand-maintained.
- Bug fixes --
set()no longer throwsECACHEFULLwhen updating an existing key atmaxKeyscapacity.flushStats()no longer breaksmaxKeysenforcement. - Performance -- TTL expiry rewritten from O(n) linear scan to O(log n) min-heap (~4x-8x faster at 100K keys in local runs). New
enableStatsoption allows stats to be disabled when beneficial (measure in your workload). - Security -- Reduced dev dependency vulnerabilities from 20 to 2 by removing grunt, coveralls, and upgrading the entire toolchain. Production dependencies have 0 known vulnerabilities. Total package count cut from 910 to 362.
- Modern Node.js -- Minimum Node.js version raised to 20 LTS. CI tested on Node 20, 22, and 24.
- Removed legacy --
enableLegacyCallbacksoption removed (deprecated since v5.0.0).
The public API (15 methods + 5 events) is unchanged. require("node-cache") is a drop-in replacement.
| Original (v5.1.2) | This fork (v6.0.0) | |
|---|---|---|
| Production vulnerabilities | 0 | 0 |
| Dev vulnerabilities | 20 (2 critical, 12 high, 3 moderate, 3 low) | 2 (mocha transitive only) |
| Total packages (incl. transitive) | 910 | 362 |
| Grunt (vulnerable toolchain) | Required | Removed |
| Coveralls (deprecated) | Required | Removed |
The original v5.1.2 ships with vulnerable versions of minimatch, form-data, qs, tough-cookie, debug, js-yaml, diff, and others via its grunt/coveralls/mocha dependency tree. This fork eliminated all but 2 (both serialize-javascript inside mocha, dev-only).
| Benchmark | Original | This fork | Improvement |
|---|---|---|---|
| TTL expiry check (100K keys) | linear scan | min-heap | ~4x-8x faster in local runs |
set+get with enableStats: false |
N/A (always on) | optional stats tracking | improvement is workload-dependent |
| useClones=false vs true | Same option | Same option | ~3x faster in local runs |
| set+get (strings) | -- | ~2.4M-3.6M ops/s | local range |
| set+get (objects, cloned) | -- | ~489K-606K ops/s | local range |
| del | -- | ~1.7M-2.0M ops/s | local range |
See CHANGELOG.md for full details.
npm install node-cache --saveconst NodeCache = require( "node-cache" );
const myCache = new NodeCache();
// set a key with 100 second TTL
myCache.set( "myKey", { name: "foo" }, 100 );
// retrieve it
const value = myCache.get( "myKey" );
// { name: "foo" }| Option | Default | Description |
|---|---|---|
stdTTL |
0 |
Default TTL in seconds for every key. 0 = unlimited. |
checkperiod |
600 |
Interval in seconds for automatic expired-key cleanup. 0 = no periodic check. |
useClones |
true |
If true, returns cloned copies of cached values. If false, returns references (faster, but mutations affect the cache). |
deleteOnExpire |
true |
If true, expired keys are deleted automatically. If false, they remain and you should handle them via the expired event. |
enableStats |
true |
If true, tracks hit/miss/size statistics. Set to false to skip stat updates for reduced overhead. maxKeys works regardless. |
maxKeys |
-1 |
Maximum number of keys allowed. -1 = unlimited. Throws ECACHEFULL when exceeded. |
const myCache = new NodeCache( { stdTTL: 100, checkperiod: 120 } );Keys can be string or number (cast to string internally). Other types throw an error.
myCache.set( key, value, [ ttl ] )
Sets a key-value pair. Optional TTL in seconds. Returns true on success.
myCache.set( "myKey", { my: "Special", variable: 42 }, 10000 );
// trueIf the key expires based on its TTL, it is deleted entirely from the internal data object.
myCache.mset( [ { key, val, ttl? }, ... ] )
Sets multiple key-value pairs at once. Returns true on success.
myCache.mset([
{ key: "myKey", val: obj, ttl: 10000 },
{ key: "myKey2", val: obj2 },
]);myCache.get( key )
Returns the cached value, or undefined if not found or expired.
const value = myCache.get( "myKey" );
if ( value === undefined ) {
// handle miss
}myCache.mget( [ key1, key2, ... ] )
Returns an object of found key-value pairs. Missing or expired keys are omitted.
const values = myCache.mget( [ "myKeyA", "myKeyB" ] );
// { "myKeyA": ..., "myKeyB": ... }myCache.take( key )
Gets the cached value and deletes the key. Equivalent to get(key) + del(key). Useful for single-use values like OTPs.
myCache.set( "otp", "123456" );
const otp = myCache.take( "otp" ); // "123456", key is now deletedmyCache.del( key ) or myCache.del( [ key1, key2, ... ] )
Deletes one or more keys. Returns the number of deleted entries.
myCache.del( "A" ); // 1
myCache.del( [ "B", "C" ] ); // 2myCache.ttl( key, [ ttl ] )
Redefines the TTL of a key. Returns true if the key exists, false otherwise. If ttl is omitted, the default TTL is used. A ttl < 0 deletes the key.
myCache.ttl( "existentKey", 100 ); // true
myCache.ttl( "missingKey", 100 ); // falsemyCache.getTtl( key )
Returns the expiration timestamp (ms) for a key, 0 if no TTL is set, or undefined if the key doesn't exist.
myCache.getTtl( "myKey" ); // 1456000600000
myCache.getTtl( "noTtlKey" ); // 0
myCache.getTtl( "missing" ); // undefinedmyCache.keys()
Returns an array of all existing keys.
myCache.keys(); // [ "all", "my", "keys" ]myCache.has( key )
Returns true if the key exists in the cache, false otherwise.
myCache.has( "myKey" ); // true or falsemyCache.getStats()
Returns cache statistics.
myCache.getStats();
// { keys: 0, hits: 0, misses: 0, ksize: 0, vsize: 0 }myCache.flushAll()
Deletes all cached data and resets statistics.
myCache.flushStats()
Resets hit/miss/size statistics without deleting data.
myCache.close()
Stops the automatic expiry check interval. Call this when you're done with the cache to allow the process to exit cleanly.
Fired when a key is added or changed.
myCache.on( "set", function( key, value ) {
// ...
});Fired when a key is removed manually or due to expiry.
myCache.on( "del", function( key, value ) {
// ...
});Fired when a key expires.
myCache.on( "expired", function( key, value ) {
// ...
});Fired when the cache is flushed.
myCache.on( "flush", function() {
// ...
});Fired when the cache stats are flushed.
myCache.on( "flush_stats", function() {
// ...
});Benchmark results and charts are available in docs/BENCHMARK_CHARTS.md.
npm run bench # full suite (median/p95/range)
npm run bench:heap # heap vs linear comparison (median/range)Key results (Node v24.12.0 on Windows x64, 7 runs per scenario):
| Benchmark | Median | Range (min-max) |
|---|---|---|
| set+get (strings) | 2.83M ops/s | 2.40M-3.57M |
| set+get (objects, cloned) | 540K ops/s | 489K-606K |
| del | 1.83M ops/s | 1.74M-1.99M |
| useClones=false vs true | 3.55x faster | 2.82M-4.55M vs 945K-1.16M |
| enableStats=false vs true | 0.95x throughput | environment-sensitive, benchmark your workload |
| TTL heap vs linear (100K keys) | 6.22x faster | 3.76x-8.16x (bench:heap) |
Full TypeScript rewrite. Public API unchanged. Internal functions and names have changed -- if you depend on internal APIs (prefixed with _), review CHANGELOG.md before upgrading. enableLegacyCallbacks removed. Node.js 20+ required.
Callbacks deprecated. Available via enableLegacyCallbacks option (now removed in v6.x). Node.js 8+ required.
Values are cloned by default. Disable with useClones: false.
.get() returns the value directly instead of { key: value }.
| Node.js | Status |
|---|---|
| 20.x LTS | Minimum supported, CI tested |
| 22.x LTS | Supported, CI tested |
| 24.x Current | Supported, CI tested |
| < 20.x | Not supported |
| Version | Date | Description |
|---|---|---|
| 6.0.0 | 2026-02-28 | TypeScript rewrite, Node.js 20+, enableStats option, min-heap TTL, bug fixes. See CHANGELOG.md. |
| 5.1.2 | 2020-07-01 | Type definition for .take(), Buffer fix. |
| 5.1.0 | 2019-12-08 | Added .take() and .flushStats(). |
| 5.0.0 | 2019-10-23 | Removed lodash, added .has() and .mset(). |
| 4.0.0 | 2016-09-20 | Fixed .ttl( key, 0 ) bug. |
| 3.0.0 | 2015-05-29 | Clone values by default. |
| 2.0.0 | 2015-01-05 | Changed .get() return format. |
See CHANGELOG.md for the complete history.
Contributions are welcome. See CONTRIBUTING.md for the process, RELEASE_POLICY.md for versioning, and MAINTENANCE.md for project scope.
Originally created by @mpneuried and sponsored by Team Centric Software. This fork is maintained by @alexanderpoliser.
Original repository: github.com/node-cache/node-cache
MIT -- Copyright (c) 2019 Mathias Peter and the node-cache maintainers
See LICENSE for the full text.
