Persistent memory API for AI agents. Store and recall across runs.
One POST to remember. One GET to recall. Persistent semantic memory for every agent — no vector DB setup required.
const res = await fetch('https://memstore.dev /v1/memory/remember', { method: 'POST', headers: { 'Authorization': `Bearer ${apiKey}`, 'Content-Type': 'application/json' }, body: JSON.stringify({ content: 'User prefers dark mode, uses React, timezone UTC-5', session: 'user_8821', ttl: 2592000 // 30 days }) });
// GET /v1/memory/recall?q=user+preferences // Response: { "memories": [{ "id": "mem_k9x2...", "content": "User prefers dark mode, uses React...", "score": 0.97, "session": "user_8821", "age": "2 hours ago" }], "tokens_used": 142 }
The entire surface area, as it was documented when the service ran.
Every session starts from zero. Your agent has no idea what the user said last week, what decisions were made, or what it already tried. That's not intelligence — that's amnesia.
Agents ask users the same things over and over. Every run re-discovers what should have been remembered.
Dumping entire conversation history into every prompt is expensive, slow, and hits context limits fast.
Without real memory, agents make up plausible-sounding facts about past interactions. Users notice.
No API key needed. Select a memory, store it, then recall it semantically.
Every run starts with full context. No re-explaining. No hallucinating past decisions.
A small, deliberately boring stack. Two endpoints doing real work, and one SQL function doing the interesting part.
pgvector extension for semantic searchtext-embedding-3-small — 1536 dimensionsRecall is one round trip. The API embeds the query, then hands the vector to Postgres, which does filtering, scoring, and ranking in a single indexed pass — no candidate set is ever shipped back to Node for re-ranking.
-- Semantic recall (cosine similarity via pgvector) CREATE OR REPLACE FUNCTION recall_memories( p_agent_id UUID, p_embedding VECTOR(1536), p_session TEXT DEFAULT NULL, p_top_k INT DEFAULT 5, p_threshold FLOAT DEFAULT 0.5 ) RETURNS TABLE ( id UUID, content TEXT, session TEXT, metadata JSONB, score FLOAT, created_at TIMESTAMPTZ ) LANGUAGE SQL AS $$ SELECT m.id, m.content, m.session, m.metadata, 1 - (m.embedding <=> p_embedding) AS score, m.created_at FROM memories m WHERE m.agent_id = p_agent_id AND (p_session IS NULL OR m.session = p_session) AND (m.ttl IS NULL OR m.ttl > NOW()) AND 1 - (m.embedding <=> p_embedding) >= p_threshold ORDER BY m.embedding <=> p_embedding LIMIT p_top_k; $$;
<=> is pgvector's cosine distance operator, so 1 - distance gives a similarity score in the same expression that drives the sort. The ORDER BY on the raw distance is what lets the ivfflat index serve the query; ordering on the derived score column instead would force a sequential scan.
Persistent memory for AI agents is the ability to store facts, decisions, and context outside the agent runtime and retrieve them semantically on future runs. Unlike context window stuffing, persistent memory scales across sessions, reduces token costs, and gives agents long-term recall without manual state management.
POST any text — facts, decisions, user preferences, tool outputs. Memstore embeds it automatically and indexes it for semantic search.
GET with a natural language query. Returns the most relevant memories ranked by semantic similarity — not just keyword matches.
Every agent run starts with full context. No loops, no repeated work, no hallucinating past decisions. Your agent gets smarter over time.
Not a vector DB tutorial — a memory layer with agent-native primitives.
pgvector cosine similarity returned the right memories even when the query wording differed. Agents did not need exact matches to remember.
Memories were tagged by user, task, or run, and recall could span sessions or stay inside a single scope. Isolation was enforced in the SQL, not just the app layer.
Any memory could carry a time-to-live. Short-lived task context expired on its own; long-term facts persisted. Expiry was filtered inside the recall query itself.
Every error response carried a machine-readable code, a human-readable message, and a suggested fix, so an agent could retry correctly without a human in the loop.
Webhooks fired when memories were created, updated, or expired, so agent state could be synced across services or trigger downstream work.
What it was used for, from customer-facing bots to internal automation pipelines.
Bots that recalled a customer's history, past tickets, and preferences, so nobody had to repeat themselves on every contact.
Agents that tracked every prospect interaction, objection, and follow-up, holding deal context across weeks of back-and-forth.
Assistants that actually knew the user — preferences, projects, habits, goals — and got more useful with each interaction.
State shared across agent handoffs: one agent stored a decision, another recalled it ten steps later, with no message-passing spaghetti.
No SDK required — any language that could make an HTTP request worked with Memstore.
Rolling your own agent memory sounds like a weekend project. It isn't.
How the alternatives compared at the time Memstore was running.
| Feature | Self-hosted pgvector | Pinecone / Weaviate | Memstore (as built) |
|---|---|---|---|
| Setup time | 2–4 hours | ~1 hour | Minutes, once you had a key |
| Embedding logic | Manual | Manual | Automatic |
| Maintenance | High | Medium | Handled by the service |
| API style | SQL + drivers | Heavy SDK | Simple REST |
| Cost to start | $25+/mo | Usage + fees | Free tier, then $19/mo |
Four endpoints. Bearer auth. JSON in, JSON out. Structured errors an agent could act on. No SDK was required, though Python and Node clients shipped alongside it.
-- memories table (Supabase pgvector) CREATE TABLE memories ( id uuid PRIMARY KEY, agent_id uuid REFERENCES agents, session text, content text NOT NULL, embedding vector(1536), metadata jsonb, ttl timestamptz, created_at timestamptz DEFAULT now() ); -- cosine similarity index CREATE INDEX ON memories USING ivfflat (embedding vector_cosine_ops) WITH (lists = 100);
Pricing as designed when the service was live.
Pay for what your agents use. Free tier generous enough to build your first production agent.
1 operation = 1 store or recall call. Most agent runs use 20–100 ops.
Agent memory holds sensitive data, so these were the guarantees the service was designed around.
Memories were stored in Postgres with encryption at rest and served over TLS only.
Every API key operated in its own namespace. Isolation was enforced in the recall SQL function, not just the application layer.
Stored memories and queries were never used to train models. The list and forget endpoints made export and deletion self-service.
Keys were bcrypt-hashed and could be rotated or revoked, each scoped to a single agent namespace.
Backend, SDKs, MCP server, and Postgres schema are all readable in the repo.
View source on GitHub →AI Hub is a free multi-AI dashboard: chat with ChatGPT, Claude, Gemini, Grok, and local Ollama models side by side. It was the first real consumer of this API — every conversation's persistent memory ran through Memstore, which made it the proving ground for session scoping and recall quality. AI Hub is still running; it no longer depends on Memstore.