Skip to content

Memory store adapters

Memory’s TYPE × STRATEGY combinations are agnostic about WHERE the bytes live. The store is the third axis — the persistence boundary that turns memory from “ephemeral local state” into “production multi-tenant state with GDPR forget + multi-instance access”. Pick by access pattern + durability needs.

StoreSubpathPeer-depVector searchWhen to use
InMemoryStore(top-level)Dev, tests, single-process scenarios
RedisStoreagentfootprint/memory-redisioredis❌ (RedisSearch later)Hot recent memory + signatures + feedback aggregation
AgentCoreStoreagentfootprint/memory-agentcore@aws-sdk/client-bedrock-agent-runtime❌ (server-side retrieve later)Bedrock-native session + event memory

All three implement the same MemoryStore interface — defineMemory({ store }) doesn’t care which one you pass. Drop-in.

The default for dev / tests. O(n) linear scan for search(); fine for thousands of entries; bounded by process memory:

import { InMemoryStore } from 'agentfootprint';
const store = new InMemoryStore();

Resets on process restart. Per-process — multi-instance deploys lose state.

Subpath import keeps the main barrel small. Lazy-required ioredis:

import { RedisStore } from 'agentfootprint/memory-redis';
const store = new RedisStore({ url: 'redis://localhost:6379' });
// or share an existing client:
// const store = new RedisStore({ client: existingIoredisClient });

Implements every MemoryStore method except search(). putIfVersion uses an atomic Lua compare-and-swap; putMany uses pipelining; forget() uses SCAN (never KEYS — KEYS blocks Redis). Tested with mock-injected _client; CI doesn’t need a live Redis.

Vector search NOT included. RedisSearch is a separate Redis module with its own API. A RedisSearchStore is planned for v2.6.

AWS Bedrock AgentCore Memory adapter. Subpath import; lazy-required AWS SDK:

import { AgentCoreStore } from 'agentfootprint/memory-agentcore';
const store = new AgentCoreStore({
memoryId: 'arn:aws:bedrock:us-east-1:...:memory/my-mem',
region: 'us-east-1',
});

Maps MemoryStore calls onto AgentCore’s session/event model. Caveats (also documented in JSDoc):

  • putIfVersion is emulated client-side (read+write). Adequate for single-writer-per-session deploys; weaker for multi-writer.
  • seen / feedback use in-process shadow state — don’t survive process restart. Use Redis for durable recognition.
  • search() not exposed today. AgentCore has a server-side retrieve API; mapping it to MemoryStore.search would be a leaky abstraction. A separate agentcoreRetrieve() helper is planned.

In hybrid memory setups (multiple .memory(...) calls on one agent), each layer can use a different store optimized for its access pattern:

import { defineMemory, MEMORY_TYPES, MEMORY_STRATEGIES } from 'agentfootprint';
import { RedisStore } from 'agentfootprint/memory-redis';
import { AgentCoreStore } from 'agentfootprint/memory-agentcore';
const recent = defineMemory({
id: 'recent',
type: MEMORY_TYPES.EPISODIC,
strategy: { kind: MEMORY_STRATEGIES.WINDOW, size: 10 },
store: new RedisStore({ url: redisUrl }), // sub-ms hot reads, TTL
});
const causal = defineMemory({
id: 'causal',
type: MEMORY_TYPES.CAUSAL,
strategy: { kind: MEMORY_STRATEGIES.TOP_K, topK: 1, threshold: 0.7, embedder },
store: new AgentCoreStore({ memoryId, region }), // managed durability
});
agent.memory(recent).memory(causal);

See Auto memory (hybrid) for the layered pattern.

StoreWhy it’s planned
DynamoDBAWS-native, globally distributed, serverless-friendly
Postgres (with pgvector)Vector search built-in; queryable + joinable with app data
Pinecone / Qdrant / WeaviateVector-first; serious-scale RAG / semantic-retrieval workloads
RedisSearchStoreVector search via the RedisSearch module

All four follow the same peer-dep + subpath import pattern as RedisStore + AgentCoreStore.

Multi-tenant identity is enforced at the store

Section titled “Multi-tenant identity is enforced at the store”

Every MemoryStore method takes MemoryIdentity as the first arg. Adapters MUST namespace internal keys by the full tuple. A bug passing the wrong identity surfaces as “no data” — not as a cross-tenant leak.