You build an agent. It works great in your first test. Then a week later it makes the same mistake you already corrected, asks a question you already answered, or treats a returning user like a total stranger. The model didn't get worse. Your agent just never had memory in the first place.
This is the gap between a demo and a system people actually rely on. A single prompt-response loop is not memory. It's a goldfish with good vocabulary.
The three things people confuse with memory
Before fixing this, name the problem correctly. Most "memory" complaints are actually one of three separate issues.
Context window. This is short-term working memory. It holds the current conversation or task, and it disappears the moment the session ends or the window fills up and older messages get truncated.
Retrieval. This is long-term factual recall - pulling relevant facts from a store of past interactions, documents, or decisions. It's not automatic. You have to build the retrieval step yourself.
State. This is the actual data your agent is supposed to track - user preferences, task status, what's already been done. It's not a memory feature at all. It's just your database, and pretending an LLM will remember it for you is how bugs happen.
⚠️ Watch out
If your "memory" system is just "stuff a summary back into the prompt," you don't have memory. You have a slowly degrading game of telephone.
Pattern 1: Scratchpad state for a single run
For anything transactional - a multi-step workflow, a research task, an n8n automation - don't rely on the model to remember what it already did. Write state to a file or a database row as you go, and pass a summary of that state back in on the next step.
// Instead of hoping the model "remembers" step 3 happened
const agentState = {
taskId: "sync-2026-07-11",
completedSteps: ["fetch_leads", "dedupe", "enrich"],
pendingSteps: ["sync_to_crm"],
lastError: null,
};
// Pass this in explicitly every single call
const prompt = `
Current state: ${JSON.stringify(agentState)}
Continue the task from where it left off.
`;
This feels almost too simple, but it's the difference between an agent that reliably finishes multi-step jobs and one that silently drops steps whenever the conversation gets long.
Pattern 2: Durable memory across sessions
This is the harder problem - remembering a user, a project, or a decision across completely separate runs, days or weeks apart. You need three pieces:
- A trigger for when something is worth saving (explicit user request, a correction, a repeated pattern)
- A store - doesn't need to be a vector database for most use cases, a structured file or a Postgres table with a
typeandcontentcolumn works fine - A retrieval step that pulls relevant memories back in before the agent responds, not the whole history
🔥 Pro tip
Most teams over-engineer step 2 and completely skip step 1. A vector database full of memories nobody decided were worth keeping is just expensive noise. Be deliberate about what gets saved.
Claude Code's own memory system is a good reference model - it separates memories by type (user context, feedback, project facts, references) instead of dumping everything into one undifferentiated blob. That separation is what makes retrieval actually useful later, because you can search the type that matches your question instead of everything the agent has ever seen.
Pattern 3: Correction memory
The most valuable memory type is also the most ignored: what the agent got wrong before. If a user corrects your agent's approach, that correction should get written down immediately, not just applied in the moment and forgotten.
function onUserCorrection(correction) {
saveMemory({
type: "feedback",
rule: correction.newApproach,
reason: correction.why,
appliesWhen: correction.context,
});
}
Without this, you'll watch your agent make the exact same mistake in every new session, because "learning" only happened inside a context window that got thrown away.
What actually breaks in production
A few failure modes show up constantly once agents leave the demo stage:
Silent context loss. Long conversations quietly drop early messages once the context window fills, and nothing tells you it happened. Log when truncation occurs so you can catch it instead of debugging a mystery.
Stale memory. A memory that was true three months ago gets treated as current fact. Timestamp everything you save and check freshness before trusting it, especially for anything that changes - prices, team structure, API behavior.
Memory as a crutch for bad prompts. If your agent needs to remember ten paragraphs of instructions every single call, that's a system prompt problem, not a memory problem. Fix the prompt first.
Start smaller than you think
You don't need a vector database, a memory framework, or a research paper's worth of architecture to fix this. Start with a JSON file that logs decisions and corrections with timestamps. Read it back in before each session starts. Expand to proper retrieval only once you've proven what's actually worth remembering.
Give your agent a memory before you give it more tools. An agent with ten tools and no memory just makes the same mistake ten different ways.
