Install lru-cache via npm
mainTo add lru-cache to your project, use the following command:
npm install lru-cache --saverepository·main·Indexed 26 days ago
https://github.com/isaacs/node-lru-cacheA high-performance Least-Recently-Used (LRU) cache implementation for JavaScript (v11.5.2). It allows developers to limit memory usage by automatically evicting the least recently accessed items based on capacity (max), total storage size (maxSize), or time-to-live (ttl) constraints.
To add lru-cache to your project, use the following command:
npm install lru-cache --saveThe cache does not store undefined because it is used internally to signal missing keys. Calling cache.set(key, undefined) is equivalent to cache.delete(key).
To track undefined values, use a unique Symbol as a placeholder:
import { LRUCache } from 'lru-cache'
const undefinedValue = Symbol('undefined')
const cache = new LRUCache({ max: 100 })
const mySet = (key, value) =>
cache.set(key, value === undefined ? undefinedValue : value)
const myGet = (key) => {
const v = cache.get(key)
return v === undefinedValue ? undefined : v
}To prevent unbounded memory growth, follow these rules:
max: Allocates storage for a specific number of items. This is the most performant method.maxSize: Sets a limit on total storage consumed. You must provide a sizeCalculation function in the constructor or a size option in cache.set(). Sizes must be positive integers.ttl: If neither max nor maxSize are set, ttl tracking must be enabled. Note that items are only purged when requested unless ttlAutopurge is enabled. If ttlAutopurge, max, and maxSize are all unset, the cache may grow unbounded.The performance of lru-cache depends on your key types. This library is optimized for repeated get operations and minimizing eviction time.
lru-fast).Note: Avoid using dispose functions, size tracking, TTL behavior, or observability features unless absolutely necessary, as these add minimal but non-zero performance overhead.
The library uses node:diagnostics_channel for metrics and tracing.
lru-cache:metrics to receive LRUCache.Status objects for synchronous operations.tracingChannel('lru-cache') to track the lifecycle of asynchronous operations like cache.fetch() and cache.forceFetch().Note: Using these features imposes a modest performance penalty. Support for node:diagnostics_channel is currently limited to Node, Bun, Deno, and compatible edge platforms.
lru-cache and compare it against other implementations (like hashlru, lru-fast, or mnemonist), use the make command within the benchmark directory.makeWhen testing TTL (Time-To-Live) functionality, the library captures a reference to the global performance or Date objects at import time. To ensure your test mocks (like jest.useFakeTimers()) are respected, you must dynamically import the package within your tests instead of using a top-level static import.
Alternatively, you can provide a custom perf option during instantiation with a now method to control time manually.
// ❌ Not recommended
import { LRUCache } from 'lru-cache'
// mocking timers, e.g. jest.useFakeTimers()
// ✅ Recommended for TTL tests
// mocking timers, e.g. jest.useFakeTimers()
const { LRUCache } = await import('lru-cache')When instantiating LRUCache, you can provide an options object to control behavior.
Required (at least one):
max: Maximum number of items to keep.maxSize: Maximum storage size (requires sizeCalculation).ttl: Time-to-live in milliseconds.Optional:
maxSize: Used for tracking overall storage size.sizeCalculation: Function (value, key) => number used to determine the size of an item for maxSize tracking.dispose: Callback (value, key, reason) => void called when an item is evicted.onInsert: Callback (value, key, reason) => void called when an item is inserted.ttl: Default time-to-live in ms.allowStale: Boolean; if true, returns stale items before removing them.updateAgeOnGet: Boolean; if true, updates the item's age when get() is called.updateAgeOnHas: Boolean; if true, updates the item's age when has() is called.fetchMethod: Async function for cache.fetch() to implement stale-while-revalidate behavior.The LRUCache constructor accepts an Options object that must define at least one type of limit to prevent unbounded memory consumption. You can limit the cache by:
max: The maximum number of items (count) allowed in the cache.maxSize: The maximum total size of all items in the cache. Requires sizeCalculation or providing a size during set().ttl: A Time-To-Live in milliseconds. Items expire after this duration.Important: If you use ttl without max, maxSize, or ttlAutopurge, the cache may grow unbounded and trigger a warning.
Import LRUCache using ESM or CommonJS. To prevent unbounded storage, you must specify at least one of max, ttl, or maxSize. For optimal performance, it is recommended to specify max so memory allocation can be done up-front.
import { LRUCache } from 'lru-cache'
// or:
// const { LRUCache } = require('lru-cache')
const options = {
max: 500,
ttl: 1000 * 60 * 5,
dispose: (value, key, reason) => {
// cleanup logic
},
onInsert: (value, key, reason) => {
// logging logic
}
}
const cache = new LRUCache(options)
cache.set('key', 'value')
cache.get('key') // "value"
cache.clear() // empty the cacheYou can pass a perf object to the LRUCache constructor to provide a custom now method. This is useful for manual time-mocking in tests without a framework.
import { LRUCache } from 'lru-cache'
let myClockTime = 0
const cache = new LRUCache<string>({
max: 10,
ttl: 1000,
perf: {
now: () => myClockTime,
},
})
// run tests, updating myClockTime as neededTo use maxSize or maxEntrySize, you must provide a sizeCalculation function. This function takes the value and key and returns a Size (number).
sizeCalculation: (value, key) => value.lengthIf sizeCalculation is not provided but maxSize or maxEntrySize are set, you must provide an explicit size in every set() call.