Choosing a Driver
@warlock.js/cache ships eight drivers. They all speak the same API — you can
swap one for another without touching call sites — but they trade off
durability, scale, and capabilities. This page helps you pick.
Quick pick
Section titled “Quick pick”| Your situation | Driver |
|---|---|
| Local dev, single process | memory |
| Session-style data that should stay alive while used | memoryExtended |
| Bounded memory footprint (cap the entry count) | lru |
| Small persistent cache, no server (CLI, build cache) | file |
| Production, multiple instances, shared cache + locks | redis |
| You already run Postgres, or need vector similarity | pg |
| Disable caching without changing code | null |
| Asserting cache behavior in tests | mock |
The 30-second decision
Section titled “The 30-second decision”- Running more than one instance? You need a shared store — go
redis(orpgif Postgres is already in your stack). In-memory drivers are per-process, so each instance would hold its own copy and invalidation wouldn’t propagate. - Need vector similarity in production?
pgwith thevectorconfig block — real pgvector index, samecache.similar()code. - Single process, just want speed?
memory. AddmaxSizeto cap it, or reach forlruwhen you want a hard entry ceiling with eviction. - Need it to survive a restart but don’t want a server?
file.
Capability matrix
Section titled “Capability matrix”| Driver | Survives restart | Multi-instance | Native locks | Native lists | Similarity | Eviction |
|---|---|---|---|---|---|---|
memory | ❌ | ❌ | emulated | read-modify-write | brute force | maxSize (LRU) |
memoryExtended | ❌ | ❌ | emulated | read-modify-write | brute force | maxSize (LRU) |
lru | ❌ | ❌ | emulated | read-modify-write | brute force | capacity (LRU) |
file | ✅ | ⚠️ same host | emulated | read-modify-write | ❌ | TTL only |
redis | ✅ | ✅ | native NX/XX | read-modify-write¹ | ❌ (backlog) | TTL / Redis policy |
pg | ✅ | ✅ | emulated | read-modify-write | ✅ pgvector | TTL only |
null | n/a | n/a | n/a | n/a | returns [] | n/a |
¹ Lists are stored as a single JSON entry and mutated read-modify-write on every
driver today. Native Redis list commands (LPUSH / LRANGE / LTRIM) are
planned for v2.1.
:::note update() / merge() support
The file driver throws CacheUnsupportedError for
update() and merge() (no atomic read-modify-write primitive on disk yet).
All other drivers support them. See
Update & Merge.
:::
Driver one-liners
Section titled “Driver one-liners”memory— an in-processMap. Fastest option, zero setup, gone on restart. The default for dev and single-instance apps. OptionalmaxSizeevicts the least-recently-used entry past the limit.memoryExtended—memorywith sliding expiration: every read refreshes the entry’s TTL. Use it for data that should stay cached as long as it’s actively used (session-ish reads) and expire only after a quiet period.lru— a hardcapacityceiling (default 1000) with least-recently-used eviction. Reach for it when bounding memory matters more than keeping every entry.file— JSON-on-disk. Survives restarts without running a server, but it’s single-host and doesn’t supportupdate()/merge(). Good for CLIs and build caches.redis— the production workhorse. Shared across instances, nativeSET NX/XXfor real distributed locks, native list commands for O(1) list ops. Similarity isn’t wired yet.pg— Postgres-backed and durable. The only driver with a real similarity index (pgvector, HNSW or IVFFlat). Bring your ownpg.Pool/Client; the driver doesn’t own the connection lifecycle.null— a black hole. Every write is a no-op, every read a miss. Swap it in to disable caching globally without touching call sites.mock— an in-memory store plus acallLogof every operation, for behavioral assertions in tests. See Testing.
Mixing drivers
Section titled “Mixing drivers”You’re not locked into one. Register several and route per call with the
driver option — keep your default hot path in memory while sending durable
or audit writes to redis:
await cache.set("user.1", user, "1h"); // default driverawait cache.set("audit.event", event, { driver: "redis", ttl: "30d" });See Configuration for registering drivers and Set Options for per-call overrides.
Related Documentation
Section titled “Related Documentation”- Configuration — register and wire drivers
- Cache Driver Interface — the contract every driver implements
- Make Your Own Cache Driver — build a custom backend
- Comparison with Other Libraries