Skip to content
Skip to main content
A developer configuring an n8n AI agent workflow on one monitor with a Postgres schema and terminal on the other
9 min readBy Carlos Aragon

n8n AI Agent Memory: Postgres vs Redis

Default to Postgres Chat Memory. It survives restarts, keeps every conversation under a durable session key, and lets you query the history later with plain SQL. Reach for Redisonly when you actually need fast session context under real concurrency — and even then, keep Postgres as the system of record. Here's the rule I use on the n8n agents I run every day, and the mistakes that taught it to me.

First: Your Agent Probably Has No Memory At All

Almost every “my n8n agent forgets everything” ticket I get comes down to the same thing: the AI Agent node is still on the default Simple (Window Buffer)memory. That memory lives in RAM. It gets wiped on every workflow restart, every redeploy, every time a worker recycles — and on a queue-mode setup it isn't even reliably shared between executions. Great for a demo. Useless the moment a real user comes back an hour later.

So the first decision isn't Postgres versus Redis. It's “stop using in-memory buffer for anything you care about.”Once you accept that, the real question is which durable store to hang off the agent — and that's where most people overthink it.

The one-line rule:

Postgres Chat Memory by default. Add Redis only when you can point at a real latency-under-load problem. Add pgvector only when the agent needs to recall old facts, not just replay recent turns.

Postgres vs Redis, Head to Head

Both nodes do the same core job: store the back-and-forth of a conversation keyed by a session ID, and hand a rolling window of it back to the model on the next turn. They differ in what happens around that job — durability, speed, and what you can do with the data later.

What mattersPostgres Chat MemoryRedis Chat Memory
Survives restartsYes — on disk by defaultOnly if persistence (AOF/RDB) is configured
Read/write latencyLow, fine for chatLowest — in-memory, sub-millisecond
Query history laterYes — plain SQL over the tableNo — it's a key/value blob
Semantic recallAdd pgvector on the same DBNeeds a separate vector store
Extra infraUsually none — you already have a DBA Redis instance to run and monitor
Best fitAlmost everythingHigh-concurrency, ephemeral session context

Notice what's missing from that table: a scenario where Redis is the obvious winner for a typical agency automation. For a WhatsApp assistant handling a few dozen concurrent conversations, or a lead-qualification agent tied to a CRM, Postgres reads and writes are nowhere near the bottleneck — the model call is. Redis earns its keep when you're fielding thousands of simultaneous sessions and every millisecond of memory I/O compounds. Most of us are not there, and pretending we are just adds a second database to babysit.

When I Actually Reach for Redis

I don't treat Redis as the “serious” upgrade over Postgres — that framing is backwards. I reach for it in specific, measurable situations:

  • High concurrency: hundreds or thousands of live sessions where memory reads and writes are genuinely on the hot path, not the model call.
  • Deliberately ephemeral context: a support bot where a session should evaporate after N minutes of silence, and a Redis TTL is the cleanest way to expire it.
  • You already run Redis: if it's in the stack for queueing or caching, adding session memory to it is low-cost.

And even then, the pattern I like is both: Redis holds the fast, short-lived session window; Postgres is the durable transcript I can query, audit, and mine later. Redis is the working memory, Postgres is the filing cabinet. If I had to keep only one, it's always Postgres — losing speed is annoying, losing the record is unrecoverable.

The Bug That Isn't Postgres or Redis: Your Session Key

Here's the twist that catches most people: the store almost never causes the memory bug. The session keydoes. That's the value n8n uses to group messages into one conversation, and there are exactly two ways to break it.

The two failure modes:

Too broad — a static key like "chat", so every user on the planet shares one conversation and their context bleeds into each other.

Too unique — mapping the key to the execution ID or a timestamp, so it changes every message and the agent greets a returning user like a stranger, every single turn.

The fix is the same regardless of Postgres or Redis: bind the session key to a stable per-conversation identifier — a WhatsApp number, a chat thread ID, a CRM contact ID. Do that and 90% of “the memory doesn't work” complaints disappear before the database is even involved. This is the same deterministic-plumbing discipline I wrote about when my n8n agents started failing silently: get the wiring right and the model has a lot less room to look broken.

My Default Setup, Step by Step

This is the memory config I drop into almost every production n8n agent, and it takes about ten minutes:

  • Delete the Simple (Window Buffer) memory sub-node. It's a prototype tool.
  • Attach Postgres Chat Memory pointed at the same database I already use for the workflow — often a Supabase Postgres.
  • Map the session key to the user or conversation ID coming off the trigger, not the execution ID.
  • Set a context window length (I usually start at 10–20 turns) so the model gets recent context without ballooning token cost — the full transcript still lives in the table.
  • Only if the agent needs to recall older facts, add a pgvector store on the same Postgres for semantic retrieval.

Putting the chat memory and the lead data in one Postgres pays off fast — I can join a conversation to the contact record it belongs to without a second hop. I lean on that same one-database pattern in the Supabase + n8n lead database I built. And bounding the context window isn't just tidiness — an unbounded window is a slow, expensive way to blow your token budget, which is exactly the kind of runaway I break down in running agents on autopilot without torching your budget.

If you want the official node reference, n8n's memory documentation walks through each memory sub-node and its settings.

The Short Version

  • If your agent forgets, check first that it isn't on default in-memory Window Buffer memory — that's the usual culprit, not the database.
  • Postgres Chat Memory is the right default: durable, queryable, no extra infra since you already have a DB.
  • Redis is for high concurrency and deliberately ephemeral sessions — reach for it on evidence, not vibes.
  • When you do use Redis, pair it with Postgres: Redis as working memory, Postgres as the permanent record.
  • Most 'memory doesn't work' bugs are a bad session key, not the store. Use a stable per-conversation ID.
  • Plain chat memory replays recent turns; it doesn't recall. Add pgvector when you need semantic recall.

Want an n8n Agent That Actually Remembers?

I build production n8n AI agents with durable memory, clean session handling, and pgvector recall wired in from the start — on Postgres, Supabase, and the Claude API. If your agent keeps forgetting its users or you're not sure which memory store you actually need, let's talk.

Related Posts