AI System Design

Design an Agent Memory System

Step 1 / 9

Learn AI system design by building a long-term memory system for an LLM agent or chatbot step by step.

The numbers to beatshort-termcontext window (transient)long-termpersistent storemovewrite ↔ recall

Deep cut · 6:23

Now pressure-test the memory you just designed

The architecture explains the happy path. This investigation starts after a private complaint leaks into a restaurant email, traces the write and recall paths backward, then rebuilds the system before turning it into an interview answer.

  • Trace the failure: write gates, typed stores, permission-filtered recall, ranking, provenance, conflict handling and deletion.
  • Defend the design: tenant isolation happens before ranking, and every functional and non-functional requirement maps to a mechanism.

In the interview room

How you’d open this design in an interview

Before any boxes: agree what it must do, pin the qualities that shape everything, then build — naming each trade-off as you make it. The walkthrough above is that exact order.

Functional requirements

What it must do — agree on these before drawing a single box.

  • Remember: after each turn/session, decide what’s worth keeping and write it to long-term memory.
  • Assemble context: build each prompt from system + recent turns + recalled memories under a token budget.
  • Recall: retrieve the few memories relevant to the current turn.
  • Store by type: episodic memories in a vector store, exact facts in a structured profile.
  • Stay coherent: consolidate — merge, dedup, resolve contradictions, decay — so memory stays bounded.

Non-functional requirements

The qualities that shape the whole design — each one names the mechanism that buys it.

Continuity across sessions, not just one chat
Move the salient parts of the context window into a persistent long-term store outside it — short-term is the window, long-term survives across sessions.
Memory stays small and high-signal
A memory writer extracts durable, salient facts/events (an LLM decides what matters), not the raw transcript.
Every prompt fits the token budget
A context builder packs system + recent turns + recalled memories, ranked by relevance and importance, truncating the rest.
Facts stay exactly correct while fuzzy recall stays flexible
A vector store for episodic/semantic recall plus a structured profile for exact facts queried directly, not by similarity.
Only the relevant few memories reach the model
Recall is RAG over memory: embed the turn, rank by relevance + recency + importance, inject just the handful that matter.
More memory doesn’t make the agent worse
Consolidation merges duplicates, resolves contradictions (newer facts supersede older), and decays stale memories to keep the store bounded.

The trade-offs you say out loud

Senior signal isn’t the boxes — it’s naming what you gave up and why it was the right price.

A memory systemover a bigger context window

A bigger window only delays the wall, costs more per call, and dilutes attention — and a window is per-session, so it never persists across sessions at all.

Distill salient memoriesover storing the raw transcript

Raw transcripts recreate the unbounded-growth problem in the store and make recall noisy. Extracting concise facts/events keeps memory small and high-signal.

Recall the relevant fewover injecting all memories every turn

All memories blow the token budget and bury the useful ones in noise. Rank by relevance/recency/importance and inject only the handful that help this turn.

Vector store + structured profileover one store for everything

Forcing exact facts through similarity search makes the user’s current name depend on a fuzzy match. Type each memory and store it by how it’s written and recalled.

Consolidate and forgetover appending every fact forever

Append-only memory bloats, duplicates, and holds contradictions similarity recall returns as equally true. Merging, superseding and decaying keep recall precise — forgetting is a feature.

What this teaches

Learn AI system design by building a long-term memory system for an LLM agent or chatbot step by step. An interactive guide covering why stuffing the whole history into context fails, short-term vs long-term memory, deciding what to remember, assembling working context under a token budget, storing memories in vector + structured stores, recalling relevant memories, consolidation and forgetting, and the unhappy paths (staleness, contradictions, privacy, poisoning).

Key takeaways

  • LLMs are stateless — without memory they forget across the window and across sessions.
  • Stuffing the whole history fails: it overflows the window, costs more, and never persists across sessions.
  • Split memory: short-term (context window) vs long-term (persistent store), moving salient info between them.
  • Write path: extract and store salient facts/events (an LLM decides), not the raw transcript.
  • Assemble each prompt under a token budget: system + recent turns + recalled memories.
  • Store by type (vector store for episodic/semantic recall, a structured profile for exact facts); recall is RAG over memory.
  • Consolidate and forget — merge, dedup, resolve contradictions, decay — so memory stays coherent, current and bounded.

Concepts covered

  • Why do agents need a memory system?
  • Stuffing the history fails
  • Short-term vs long-term
  • The write path
  • Assembling working memory
  • Vector + structured stores
  • The recall path
  • Consolidation & forgetting
  • Staleness, privacy & poisoning

Design an Agent Memory System — read the full walkthrough as text

the same steps, decisions & trade-offs, for reading, reference & search

The big idea

Why do agents need a memory system?

An LLM is stateless — it only knows what's in its context window right now. So a chatbot forgets your name the moment the conversation scrolls past the window, and remembers nothing from yesterday's session. For an agent or assistant meant to know you over weeks of conversations, that's fatal: no continuity, no personalization, no learning from past interactions.

An agent memory system gives a stateless model persistent memory: it decides what to remember from each conversation, stores it outside the context window, and recalls the relevant bits into the prompt when they matter — plus consolidates and forgets so memory stays coherent and bounded. It's RAG, but the corpus is the user's own history.

How to read this: Each step opens with a real design decision — make the call before I show you what ships. Watch the pipeline grow, and at the end wipe long-term memory and disable consolidation to see continuity and coherence break. Hit Begin.

Step 1 · Why not just keep everything?

Stuffing the history fails

The naive fix: append the entire conversation history to every prompt. It preserves everything — so why does it break down fast?

Design decision: Append the whole conversation history to every prompt. Why does this fail?

The call: History grows past the context window, costs more and slows every call, and still carries nothing across sessions. — Unbounded history eventually overflows any window, inflates token cost and latency on every turn, and dilutes the model's attention — and once a session ends, the window is gone, so there's no cross-session persistence at all. You need to store distilled memory outside the window and recall selectively.

Appending everything fails three ways: history eventually exceeds the context window; even before that it makes every call slower and costlier (and dilutes attention over long context); and it provides no cross-session persistence — when the session ends, the window is gone. The answer isn't a bigger window; it's to distill memory, store it outside the window, and recall selectively what's relevant now.

The window is not memory: The context window is working memory — small, transient, expensive per token. Real memory must live outside it, persistently, and be pulled in only when relevant. Conflating "put it in context" with "remember it" is the mistake; separating them is the whole design.

Step 2 · Two kinds of memory

Short-term vs long-term

Human memory isn't one thing, and neither is an agent's. What are the two layers, and what does each do?

Split memory in two. Short-term / working memory = the context window: the recent turns and the system prompt the model sees right now — small and transient. Long-term memory = a persistent store outside the window that survives across turns and sessions. The system's job is to move the salient parts of working memory into long-term storage (write), and pull the relevant parts of long-term storage back into working memory when needed (recall). Everything else is how you do those two moves well.

Working set + persistent store: It's the classic memory hierarchy: a tiny fast working set (context window) backed by a large persistent store (memory DB). You can't hold everything in the working set, so you page the relevant memories in on demand — exactly like caching, but for meaning.

Step 3 · What to remember

The write path

You can't store every word (that's the failed approach). So after a turn or session, you must decide what's worth keeping. How?

Design decision: You can't store everything. What do you write to long-term memory?

The call: The entire raw transcript, verbatim. — Storing raw transcripts recreates the unbounded-growth problem in the store and makes recall noisy. You distill: keep salient facts/events, not every word.

Run a memory writer that extracts the salient information — durable facts about the user, decisions, preferences, key events — usually with an LLM deciding what matters, and stores concise memories rather than the raw transcript. Decide when to write (after each turn, or a summary at session end) and what type (a fact vs an event). Distilling at write time keeps memory small, high-signal, and easy to recall — the opposite of dumping everything.

Distill, don't dump: The write path is where memory quality is set: an LLM extracting "user prefers Python, is building a startup, dislikes verbose answers" beats storing 50 messages. Good extraction (and typing memories as facts/events/preferences) makes everything downstream — recall, consolidation — work better.

Step 4 · Build the prompt

Assembling working memory

Every model call needs its context assembled from several sources under a hard token budget. What goes in, and how do you fit it?

A context builder assembles each prompt from: the system prompt, the recent turns (short-term), and the recalled long-term memories relevant to this turn — all packed within the token budget, prioritizing the most important/relevant and truncating or summarizing the rest. This is the moment memory becomes useful: the right past facts are placed into the window right when they're needed, so the stateless model behaves as if it remembers.

The context is a budget: Assembling context is a packing problem under a token limit: system + recent history + recalled memories, ranked by relevance/importance. Spend the budget on what helps this turn. The builder is the join point between working memory and long-term recall.

Step 5 · Where memories live

Vector + structured stores

Memories aren't all the same shape. "The user seemed frustrated last week" (fuzzy, recall by similarity) is different from "the user's name is Sam" (a fact you look up exactly). Where do they go?

Use the right store per memory type. A vector store holds embedded memories for semantic recall ("find memories related to what they're asking now") — great for episodic/fuzzy memory. A structured store / profile holds authoritative facts (name, preferences, settings) queried directly, not by similarity, so they're always correct and current. (Some systems add a knowledge graph for relationships.) Match storage to how each memory is written and recalled.

Semantic + structured: Episodic memory (events, gist) fits a vector store recalled by similarity; semantic facts about the user fit a structured profile queried exactly. Using one for the other hurts: you don't want the user's current name to depend on a fuzzy similarity match. Type your memory, store it accordingly.

Step 6 · Pull the right memories

The recall path

At each turn, of potentially thousands of stored memories, only a few are relevant. Injecting all of them is impossible (token budget) and injecting the wrong ones misleads the model. How do you recall well?

Design decision: Thousands of memories exist; only a few are relevant now. How do you recall the right ones?

The call: RAG over memory: embed the current turn, retrieve the most relevant memories (with recency/importance), inject those. — Treat the memory store as a corpus: embed the current query/turn, retrieve the top relevant memories by similarity (often blended with recency and an importance score), pull exact facts from the profile, and inject just those into the context. It's retrieval-augmented generation where the corpus is the user's own history.

Recall is RAG over memory. Embed the current turn, retrieve the most relevant memories from the vector store (often blending similarity with recency and an importance score), fetch exact facts from the profile, and inject just those into the context. Of thousands of memories, only the handful that matter now reach the model — enough for continuity, few enough to fit the budget and avoid misleading noise.

Relevance + recency + importance: Pure similarity isn't enough; good recall ranks by a mix of relevance to the current turn, how recent a memory is, and how important it was judged at write time. This surfaces the right past context without flooding the window — the read side of the memory system.

Step 7 · Keep it coherent

Consolidation & forgetting

Left alone, memory grows forever, accumulates duplicates, and holds contradictions (the user moved cities; both the old and new fact are stored). More memory then makes recall worse. How do you keep it healthy?

Run consolidation (a background process, like sleep for memory): summarize and merge related memories, deduplicate, resolve contradictions (newer/authoritative facts supersede older ones), and decay/forget stale or low-importance memories so the store stays bounded. This keeps recall precise and memory current — critically, an update to a fact (name change, new preference) must overwrite/supersede, not just add another contradictory memory.

Merge, resolve, decay: Without consolidation, memory bloats and contradicts itself, and similarity recall happily returns stale facts alongside current ones. Consolidation compresses (summaries of many episodes), reconciles conflicts, and forgets — so memory improves the agent instead of slowly poisoning it. Forgetting is a feature.

Step 8 · The sharp edges

Staleness, privacy & poisoning

Memory has dangerous failure modes: recalling stale/contradictory facts, poor recall precision (right memory not surfaced, or wrong one injected), sensitive PII stored indefinitely, and memory poisoning (a user planting false "facts" the agent later trusts).

Fight staleness with consolidation and by preferring the authoritative profile for facts (and timestamping memories). Improve recall precision with better ranking, importance scoring, and typed memories. Handle privacy: treat memory as sensitive user data — consent, encryption, retention limits, and a "forget me" that truly deletes. Defend against poisoning by not blindly trusting extracted "facts" (especially security-relevant ones), validating/attributing memories, and scoping memory per user. And watch cost — recall + write + consolidation are extra model/DB calls per interaction.

Design for the unhappy path: Stale facts → consolidate + prefer profile + timestamps. Bad recall → rank + type + score. PII → consent, encryption, deletion. Poisoning → don't blindly trust, attribute, scope per user. Memory makes an agent personal and powerful — and turns its data into a privacy and trust surface you must protect.

You did it

You just designed an agent memory system.

  • LLMs are stateless — without memory they forget across the window and across sessions.
  • Stuffing the whole history fails: it overflows the window, costs more, and never persists across sessions.
  • Split memory: short-term (context window) vs long-term (persistent store), moving salient info between them.
  • Write path: extract and store salient facts/events (an LLM decides), not the raw transcript.
  • Assemble each prompt under a token budget: system + recent turns + recalled memories.
  • Store by type (vector store for episodic/semantic recall, a structured profile for exact facts); recall is RAG over memory.
  • Consolidate and forget — merge, dedup, resolve contradictions, decay — so memory stays coherent, current and bounded.
built to remember you across a thousand chats without drowning in every word — make the calls, wipe the memory, run the gauntlet.
Finished this one? 0 / 61 AI System Designs done

Explore the topic

See this alongside everything else on the same subject — handbooks, system designs, challenges and tools, in one place.

More AI System Designs