FlowKit

Conversation memory in an n8n AI Agent: Simple Memory vs Postgres Chat Memory

Published 20 July 2026 · 6 min read

An n8n chatbot that answers the first question perfectly, then seems to lose the thread by the second or third follow-up, almost never has a prompt problem. The problem is almost always memory: either it isn't configured, or it's configured in a way that doesn't survive an n8n instance restart, or it's mixing up two different users' conversations. Each of these three failures has a precise cause and a simple fix once you know where to look.

What an AI Agent's memory actually does

n8n's AI Agent node doesn't "remember" anything on its own: every workflow execution starts from an empty context. What creates the illusion of a continuous conversation is a memory sub-node wired into the agent, which re-injects the history of previous exchanges into the prompt sent to the model before each new question. Without that sub-node, a conversational agent answers every message as if it were the first — including in a pipeline built on the WhatsApp RAG chatbot or the question-answer API from our Supabase RAG guide.

Two memory sub-nodes cover most use cases: Simple Memory (formerly Window Buffer Memory), which keeps history in RAM for the duration of the execution, and Postgres Chat Memory, which writes it to a persistent SQL table.

Why Simple Memory works fine — until it doesn't

Simple Memory stores recent exchanges directly in the n8n process's memory. For testing in the editor or a demo, that's plenty: zero configuration, zero external dependency. The problem shows up in production, in three very common scenarios:

  • A restart or redeploy of the instance wipes the ongoing history — the user picks up a conversation started the day before and the agent remembers nothing.
  • Queue mode with multiple workers (common in self-hosted setups past a certain volume, see our n8n self-hosted vs cloud comparison) spreads executions across several processes: nothing guarantees the next message in the same conversation lands on the worker that kept the history in memory.
  • A long conversation stretching over several hours: in-memory storage doesn't survive an expiring webhook, a container going to sleep, or simply the normal lifecycle of an n8n execution triggered on demand rather than kept running continuously.

In all three cases, the fix is the same: persist the history outside the n8n process.

The Session Key: the key that isolates each conversation

Before getting to persistence, a more fundamental point: whether memory lives in RAM or in a database, it's always indexed by a Session Key. That identifier is what tells the node "here's the history for this specific conversation, not another one." A poorly chosen Session Key — a fixed value, say, or one derived from a field that doesn't actually identify the user — means two different people can end up sharing the same history, with the agent answering one person based on messages from the other. That's a real privacy risk, not just a cosmetic bug.

Good Session Key candidates depend on the channel:

  • Native n8n chat: the session ID auto-generated by the Chat Trigger.
  • WhatsApp or Telegram: the sender's phone number or ID, stable across messages.
  • Slack: the thread or channel identifier, so each discussion thread keeps its own memory.
  • A chat widget on a website: a UUID generated client-side on the first message and sent back on every following call (stored in localStorage or a session cookie).

Postgres Chat Memory: persisting history with no extra infrastructure

The Postgres Chat Memory sub-node writes every exchange to a SQL table, identified by standard Postgres credentials — exactly the same ones used for a Supabase pgvector project, as described in our n8n-Supabase connection guide. Three settings are enough:

  1. Postgres credentials — pointed at your existing Supabase instance or a dedicated database.
  2. Session Key — the conversation identifier chosen per channel (see above).
  3. Table Name — the node creates the table automatically if it doesn't exist yet; no need to hand-write SQL to get started, unlike the pgvector table, which does need the extension and index described in our RAG guide.

The advantage for a team that already has a RAG Assistant Pack running: no extra infrastructure piece at all. The same Supabase project hosts both the embeddings for document search and the conversation history — two separate tables in one database, one set of credentials to maintain.

The context window / cost tradeoff

Every memory sub-node exposes a context window setting: the number of past exchanges re-injected into the prompt on each new question. That number has a direct impact on the bill, a topic covered in detail in our article on tracking AI call costs: the wider the window, the more input tokens each model call consumes, even when the user asks a short question.

Too narrow a window, conversely, breaks coherence as soon as a conversation passes three or four exchanges — the agent "forgets" a preference mentioned two messages earlier. In practice, a window of 10 to 20 exchanges covers the vast majority of support or documentation use cases; beyond that, it's better to periodically summarize older history than to resend it in full on every call.

Redis Chat Memory: an alternative for high volume

For a very high-traffic agent where read/write latency matters more than operational simplicity, Redis Chat Memory plays the same role as Postgres Chat Memory but on an in-memory store, faster on reads. The tradeoff: one more infrastructure piece to run and monitor. For the vast majority of n8n chatbots — customer support, an internal documentation assistant, lead qualification like in our article on qualifying inbound leads with AI — Postgres Chat Memory remains the simplest default, especially when a Supabase database already exists in the pipeline.

Steps to wire Postgres Chat Memory into an existing agent

  1. Add the Postgres Chat Memory sub-node and connect it to the AI Agent node's "Memory" input.
  2. Fill in Postgres credentials pointing at your Supabase project.
  3. Configure the Session Key with the identifier suited to the channel (see above) — this is the step most often skipped.
  4. Set the context window to a reasonable value (10-20 exchanges to start) and adjust by observing actual behavior.
  5. Test a multi-exchange conversation, restart the workflow or instance, then resume the same conversation: the history should be intact.

Common pitfalls

  • A Session Key shared by mistake across two different channels (for instance, the same identifier for the web widget and the API), which merges two histories that should stay independent.
  • History never purged: for a use case under data-retention constraints, a chat history table that grows indefinitely raises the same governance question as the audit trail described in our GDPR with Supabase guide — plan for periodic purging of old conversations.
  • Context window left at a default value and never reconsidered once the real conversation volume is known.
  • Confusing conversation memory with a knowledge base: chat memory retains what was said in this conversation; it doesn't replace a RAG pipeline for querying documents.

Going further

Persistent memory is just one piece among several for making a production AI agent reliable. Once conversation history is secured, the natural next questions are error handling and retries, rate-limiting AI calls if conversation volume climbs, and measuring answer quality with our article on evaluating AI workflows. The RAG Assistant Pack (€119) includes a citation-backed chatbot already built on this Supabase foundation — wiring Postgres Chat Memory into it requires no extra infrastructure. For a project combining email triage, a documentation assistant, and compliance reports, the Complete FlowKit Bundle (€269 instead of €347) brings all three packs together on the same Supabase base.

FAQ

Frequently asked questions

Is the Simple Memory node useless in production?

No, it has its place for a prototype or a single-user agent running continuously on one instance. The problem shows up as soon as a restart, a deployment, or queue mode with multiple workers enters the picture: in-RAM memory disappears or isn't shared across workers, and the agent 'forgets' mid-conversation.

Do I need a dedicated Postgres database for Postgres Chat Memory?

No. If you already have a Supabase project for a RAG pipeline or an audit trail, the same project can host the conversation history table: the node creates its table automatically on first call, no SQL script to write by hand.

How do I avoid one user seeing another user's history?

By making sure the Session Key is unique and stable per conversation: the Chat Trigger's session ID, the phone number for WhatsApp, the Slack thread identifier, or a UUID generated on the first message and sent back to the client. A Session Key that stays constant across two different users is the number-one cause of context leaks.

Should the full history always be sent back to the model?

No: the context window parameter caps how many past exchanges are sent back to the model on each call. Too wide a window drives up the token bill without necessarily improving the answer; too narrow a window loses the thread of a conversation spanning several exchanges.

Bundle FlowKit Complet

€269