
Skill
tanstack-ai-memory-redis
wire TanStack AI Redis memory adapter
Description
Use when wiring redis() from @tanstack/ai-memory/redis in production — covers client setup (ioredis or node-redis via fromNodeRedis), the storage model, client-side ranking limits, and troubleshooting.
SKILL.md
Redis Memory Adapter
Production-grade recall/save adapter backed by plain Redis (no vector index
required). Ranks client-side (lexical + optional cosine + recency + importance).
Setup
Bring your own Redis client. ioredis wires in directly; redis (node-redis v4+) needs
a small wrapper.
Option A: ioredis
import Redis from 'ioredis'
import { memoryMiddleware } from '@tanstack/ai-memory'
import { redis } from '@tanstack/ai-memory/redis'
const client = new Redis(process.env.REDIS_URL)
const memory = redis({ redis: client, prefix: 'myapp:memory' })
memoryMiddleware({ adapter: memory, scope })
Option B: redis (node-redis v4+)
import { createClient } from 'redis'
import { memoryMiddleware } from '@tanstack/ai-memory'
import { redis, fromNodeRedis } from '@tanstack/ai-memory/redis'
const client = createClient({ url: process.env.REDIS_URL })
await client.connect()
const memory = redis({
redis: fromNodeRedis(client),
prefix: 'myapp:memory',
})
memoryMiddleware({ adapter: memory, scope })
node-redis exposes a camelCase API (sAdd, mGet); fromNodeRedis translates it
to the lowercase RedisLike shape. Passing a raw node-redis client without the wrapper
throws client.sadd is not a function.
redis() accepts the same topK / minScore / kinds / embedder / extract options
as inMemory().
Storage model
{prefix}:record:{id} -> JSON record
{prefix}:index:{tenantId or _}:{userId or _}:{threadId} -> Set<id>
save writes the record and adds it to the scope's index set; recall loads the set,
scores, and renders. Scope values are escaped (:, \, and _) so a delimiter or the
unset placeholder inside a dim can't collide two scopes.
Hard cut: there is no dual-read of older index layouts. If you previously wrote under
a different shape (e.g. without tenantId), reindex or wipe — old keys are orphaned.
Always pass the same tenantId/userId/threadId on write and read: missing optional
dims become _, so omit ≠ "match any".
Ranking limits
Ranking is client-side: recall loads every record for the scope into Node and scores
it. Fine up to ~10k records per scope. Beyond that, write a vector-index-aware adapter
against the same recall/save contract.
Troubleshooting
- Records not visible across processes: ensure every process uses the same
REDIS_URLandprefix. - Malformed JSON rows: a row whose JSON won't parse is skipped on read and left in
place (never deleted) — the signal is a one-time
console.warnper bad id. Fix or delete the offending{prefix}:record:{id}key to remediate.
More skills from the ai repository
View all 19 skillsai-code-mode
execute sandboxed TypeScript code with LLMs
Jul 16AI SDKCode ExecutionSandboxingTanStack +1ai-core
configure TanStack AI agent features
Jul 17AgentsAIMiddlewareai-core/adapter-configuration
configure AI provider adapters
Jul 16AI SDKConfigurationLLMTanStackai-core/ag-ui-protocol
implement TanStack AI streaming protocol
Jul 16API DevelopmentLLMTanStackai-core/chat-experience
implement chat experiences with TanStack AI
Jul 23API DevelopmentFrontendLLMTanStackai-core/custom-backend-integration
integrate custom backends with TanStack AI
Jul 17AIAPI DevelopmentBackendTanStack
More from TanStack
View publisheraggregation
perform data aggregation in TanStack Table
table
Jul 26Data AnalysisFrontendTanStackapi-not-found
diagnose TanStack Table API errors
table
Jul 26DebuggingFrontendTanStackcell-selection
select rectangular cell ranges in tables
table
Jul 26Data AnalysisTanStackUI Componentsclient-vs-server
manage TanStack Table data pipelines
table
Jul 26Data PipelineFrontendPerformanceTanStackcolumn-faceting
build faceted filter UIs
table
Jul 26Data VisualizationFrontendTanStackcolumn-filtering
implement column filtering in TanStack Table
table
Jul 26Data AnalysisFrontendTanStack