FAQ
Common questions, with honest answers.
Can I use it with Redis Cluster?
Not yet. Lua scripts assume keys hash to the same slot. Use a single Redis instance, or design your key functions to use hash tags so all keys touched by one operation land on the same slot. Cluster support is on the roadmap.
Does it protect against cache stampedes?
No built-in singleflight. Combine with p-memoize or dataloader at the application level if you need it.
Can I store binary data?
Yes — use Buffer fields with the default TAGGED_SERIALIZER. They round-trip losslessly. See Serializers.
How does it compare to bare ioredis?
ioredis is the transport. This package adds normalization, hydration, atomic mutation Lua scripts, ZSET list management, cascade invalidation, circuit breaker, retries, metrics, compression, and TypeScript-native schema typing on top.
Can I read/write outside the schema?
Yes — RedisConnectionManager is exported, but you lose all the safety guarantees. Prefer adding a schema entry.
What happens to nested entities when I overwrite a parent?
They're written to their own keys; the parent stores only id references. So updating the parent's title does NOT touch the children. Updating a child by id is what changes it.
Why two list types?
list is fast and simple for tiny collections. indexedList (ZSET) scales to millions, supports pagination and atomic trim, and is the right answer for any feed or timeline. New code should default to indexedList.
Does NODE_ENV=production change behaviour automatically?
Yes — safety.productionMode defaults from NODE_ENV at construction time. In production, clearAllCache additionally requires { allowProduction: true }. Library consumers should pass safety explicitly to drop the env coupling.
How do I scale beyond ~30k ops/sec on one Node process?
Run multiple Node processes behind a load balancer (PM2 exec_mode: 'cluster', Kubernetes pods, etc.). Each process opens its own pool. Off-thread JSON inside the library is not implemented; multi-process is the simpler, more effective fix.
Why is `undefined` not tagged in the serializer?
It is intentionally kept identical to "field omitted" so the merge logic doesn't accidentally clobber existing values on partial updates. See Null vs Undefined.