The single most common question after “what’s an agent” is “how do I give it memory” — and the answers floating around the internet skip straight to vector databases and embeddings, which is like teaching someone to drive by explaining fuel injection. This guide is the version we actually use: a two-memory model that covers nearly every real use case, the concrete implementations in the tools you already use, and the failure modes that make agents seem dumber than they are.

The two-memory model

Human memory is a mess of types, but for agent-building purposes you only need two, and they map to things you already understand:

Working memory = the context window. Everything the model can currently “see”: your instructions, the conversation so far, the results of tool calls, the document it’s reading. It’s powerful but short-lived — when the run ends, it’s gone. And it has a hard size limit, which is the engineering constraint everyone eventually hits.

Long-term memory = storage you manage. Anything that survives between runs: last week’s research summaries, the client’s preferences, which leads were already contacted. The model doesn’t “have” this memory — your workflow fetches it and puts it into the context window where the model can use it. Long-term memory is not a model feature; it’s a system you build around the model.

That second sentence is the one that reframes everything for most people. The model is stateless; the memory is your pipeline.

Working memory management: the part everyone gets wrong

The context window fills faster than you’d think, and when it’s full, something gets dropped — usually silently, usually the wrong thing. The three techniques for keeping a long task coherent, in the order we’d learn them:

1. The conversation buffer. Keep the last N turns verbatim. Simple, and what most chat-style agents do by default. Fine until the conversation gets long.

2. The rolling summary. Older turns get compressed into a running summary (“so far the user asked about X, we established Y, the open question is Z”) while recent turns stay verbatim. This is the workhorse pattern for long tasks — most agent frameworks have a node for it, and in n8n it’s the “Window Buffer Memory” plus a summarization step. The art is what the summary keeps: outcomes and decisions, not prose.

3. Externalize the state. For really long tasks, write the working state (findings, decisions, next steps) to a document after each major step, and inject the latest state at the start of each model call. The model effectively “re-reads its own notes” every step. This is how you run tasks that take hours despite a context window that holds minutes — and it’s the same trick humans use with a whiteboard.

The failure mode that sends people to this guide: an agent that starts forgetting the task halfway through, or contradicts itself at step 12. That’s the context window overflowing or being rebuilt per-step without the summary. The fix is always one of the three techniques above — the model isn’t “dumb,” your state-passing is missing.

Long-term memory: three tiers by sophistication

Tier 1 — structured storage, keyed lookup. A spreadsheet or database table the agent queries by exact fields: client_id, date, topic. “What did we discuss with Acme Corp last month?” is a SQL query, not a semantic search. This covers most business-agent memory needs, costs nothing, and is auditable — you can look at the table and see exactly what the agent “knows.”

Tier 2 — the notes file. A running document (one per client, per project, per topic) that the agent both reads and appends to. After each significant interaction, a step writes a dated note: “Oct 22: client said they prefer weekly summaries over daily.” Before the next interaction, the agent reads the file. This is how you build “an agent that knows the client” without any exotic infrastructure — and it’s genuinely the pattern behind most “wow” agent demos once you strip the marketing.

Tier 3 — vector/semantic search. Embed documents into a vector store (Pinecone, Qdrant, pgvector, Supabase’s vector type) and retrieve by meaning rather than exact match. This earns its complexity only when: (a) the corpus is large (thousands of chunks), (b) queries genuinely can’t be keyed (“what’s our policy on refunds for digital goods?” over 800 policy docs), and (c) the agent is answering questions more than following procedures. If your use case is “remember what we did with this client,” Tier 1 or 2 does it better and cheaper.

Implementing memory in n8n and Make

Both tools ship memory nodes that cover Tier 1 and the buffer patterns, and both connect to vector stores for Tier 3:

n8n: the AI Agent node has memory sub-nodes (Window Buffer, Summary Buffer, and Postgres/Redis-backed options). For long-term memory, the pattern we use is a “Read notes” step before the agent runs and an “Append note” step after, both pointed at a Postgres table or a simple file. The tool-calling loop keeps working memory coherent inside a run.

Make: the AI Agents module has conversation memory (bounded by the scenario’s context) plus a growing set of memory integrations. The same read-before/append-after pattern works with Make’s database and Google Sheets modules. One Make-specific gotcha: each module execution is independent, so the conversation must be passed explicitly between scenarios — there’s no implicit “the agent remembers” between separate scenario runs.

The universal gotcha, worth its own paragraph: in visual tools, the memory wiring is yours to build. The agent node doesn’t automatically carry context from the previous scenario run, or even between separate agent nodes in the same scenario. When your agent “forgets,” the bug is almost never the model — it’s a missing wire between the storage and the context.

The Tier 2 notes-file pattern, wired in detail

Because “read notes before, append notes after” is the pattern we deploy most, here it is as an actual n8n configuration, since the devil is in the node order:

  1. Read notes (before the agent). A Postgres “Execute Query” node (or Google Sheets “Read Rows” if you’re staying simple): SELECT note_text, created_at FROM agent_notes WHERE client_id = {{ $json.client_id }} ORDER BY created_at DESC LIMIT 20. The LIMIT matters — notes accumulate, and stuffing two years of notes into context is the Tier 2 equivalent of a context overflow. Twenty recent notes is almost always the useful window.

  2. Inject into the system prompt. In the AI Agent node’s system message, after the task instructions: ## Client context (from memory, most recent first):\n{{ $json.notes }}. Position matters: instructions first, memory second, so the model treats the notes as background rather than a to-do list.

  3. The agent runs its loop. No memory changes mid-run — notes are read once, not live.

  4. Append note (after the agent). A second Postgres node, not part of the agent loop: INSERT INTO agent_notes (client_id, note_text, created_at) VALUES ({{ client_id }}, {{ summary }}, NOW()). The summary field is the interesting one — see the next paragraph on what goes in it.

  5. The summarizer step. Between the agent and the append, one LLM chain node compresses the interaction into an outcome-shaped note. The prompt we use: “Summarize this interaction in 1-3 sentences for future reference. Keep only decisions, preferences, commitments, and constraints — drop pleasantries and process. If nothing worth remembering happened, return exactly NOTHING.” That last escape hatch is load-bearing: without it, every interaction generates a note, and the notes file fills with noise like “client said thanks.”

In Make, the same five steps map to a Data Store read module, the agent module, an OpenAI module, and a Data Store write — same order, same LIMIT-20 discipline, same summarizer.

The whole pattern is buildable in under an hour, uses infrastructure you already have, and — the part we keep having to defend — it outperforms a vector database for “agent that knows the client” by every measure we’ve tested: recall of specific facts, cost per interaction, and the ability to open the table and read exactly what the agent knows. Vector search finds similar content; keyed lookup finds the right content, and business memory is usually the latter.

Troubleshooting memory failures

When an agent appears to have memory problems, diagnose in this order:

It forgets mid-task (contradicts itself at step 10). Working memory problem: the context is being rebuilt per-step without the buffer or summary attached. In n8n, check that the memory sub-node is actually connected to the agent node; in Make, check the conversation is passed between agent modules. This is the “missing wire” from the gotcha above and it is, in our experience, 60% of all “my agent has dementia” reports.

It forgets between runs but remembers within one. That’s not a bug — that’s the absence of long-term memory, which is the default. Wire the read-before/append-after pattern. The symptom that confirms this diagnosis: the agent handles a new client interaction perfectly but treats a returning client as a stranger.

It “remembers” things that never happened. Hallucination, not memory — the model is inventing plausible context because the actual notes are missing or empty. Check the notes table: if the append step has been failing silently (a column name mismatch after a schema change is the usual culprit), the agent has been running on an empty context and improvising. This is why the notes table should have a last_appended_at you can eyeball, and why an empty-table alert is worth ten minutes to build.

It remembers too much and gets confused. The notes file has grown unpruned and now contains contradictions — “prefers email” and “prefers Slack,” both true, different years. Fix: the pruning ritual from the mistakes section, plus the LIMIT-20 read so the worst case is bounded. A quarterly review where the agent itself proposes notes to archive (“which of these are stale?”) works well and takes minutes.

Summaries are useless (“discussed timeline at length”). The summarizer prompt is summarizing prose instead of outcomes. Tighten it with the decisions/preferences/constraints-only rule from the wired example above, and add the NOTHING escape hatch so trivial interactions don’t generate notes at all.

The diagnostic frame for all of these: memory is a pipeline you built, so debug it like a pipeline — check what’s in storage, check what got read, check what got injected, check what got written back. Every memory failure we’ve ever debugged was a break in one of those four links, and the model was always the innocent party.

The three mistakes, again

  1. Starting at Tier 3. Vector DBs are fashionable; a sheet the agent queries by client_id is debuggable. Start at Tier 1, upgrade when keyword lookup measurably fails.
  2. Summarizing prose instead of outcomes. “The user talked at length about their timeline” is a useless summary. “Timeline: must launch by March 15; board meeting Jan 20 is the hard constraint” is what the model actually needs in its context next time.
  3. Never pruning. Long-term memory that only grows eventually pollutes — old notes contradict new reality (“client prefers email” from 2024, but they’ve moved to Slack). Every few weeks, have the agent (or a human) review and archive stale notes. Memory curation is part of memory.

The mental model to keep

You are not “giving the model memory.” You are building a system where the right facts arrive in the context window at the right moment — working memory managed within the run, long-term memory fetched from storage you control. The model is the reasoning engine that operates on whatever you’ve assembled for it.

Once this clicks, the whole agent space gets less mysterious: “memory products” are storage plus retrieval pipelines, “agent frameworks” are loop managers plus context assemblers, and your n8n/Make workflow is exactly as capable of memory as the wires you draw. Draw good wires.