teachyou.ai academy
← All posts
Workflow AutomationRAGn8nVector DatabasesAI Agents

Using n8n Vector Store Nodes for RAG

Pramod Dutta · Jun 25, 2026 · 13 min read

An n8n vector store node lets you insert, update, and query embeddings inside a no-code workflow, which means you can build a working RAG pipeline without standing up a separate retrieval service. n8n ships dedicated nodes for Pinecone, Qdrant, Supabase, PGVector, Weaviate, Milvus, MongoDB Atlas, Zep, and a few others, plus a generic "Simple Vector Store" for prototyping in memory. This article walks through what these nodes actually do under the hood, how to build an ingestion workflow and a retrieval workflow, how to hook them into n8n's AI Agent node, and the mistakes that trip people up the first time.

What n8n vector store nodes actually do

Every vector store node in n8n is a thin wrapper around a database client plus an embeddings call. The node itself does three things: it accepts documents (raw text or already-chunked text with metadata), it calls an embeddings provider you've connected (OpenAI, Cohere, Google, a local Ollama model, whatever you've configured as a credential), and it writes the resulting vectors to the backing store you picked. On the query side, it takes a text input, embeds that input with the same embeddings model, and runs a similarity search against the store, returning the top-k matching chunks with their metadata and similarity scores.

This matters because the node is not the vector database. Pinecone, Qdrant, and the rest are separate services you provision yourself; n8n is the orchestration layer that talks to them. If you already run Qdrant in Docker or have a Pinecone index, the n8n node just needs credentials and an index/collection name. If you don't have a store yet, the "Simple Vector Store" node keeps everything in memory for the lifetime of a single workflow execution, which is useful for testing a RAG pipeline before you commit to infrastructure, but it doesn't persist between runs.

Each vector store node in n8n actually has two operating modes selectable from a dropdown on the node itself:

  • Insert/Update mode: takes a Document input (usually from a Text Splitter node upstream) and writes chunks plus embeddings to the store.
  • Retrieve mode: takes a query string and returns matching documents. This mode also exposes a "Retrieve as Tool" variant, which turns the node into a callable tool for an AI Agent node instead of a workflow step you wire manually.

Knowing which mode you're in matters because the same node type looks different in the canvas depending on the mode, and it's easy to leave a node in insert mode by accident when you meant to query it.

Setting up a vector store node for ingestion

Assume you're building a documentation RAG bot and you have a folder of markdown files you want searchable. The ingestion workflow has five stages: read the source, extract text, split into chunks, embed, and write to the store.

A minimal ingestion workflow in n8n looks like this, described node by node:

  1. Read Binary Files or HTTP Request node to pull in your source documents.
  2. Extract from File node (or a Code node if your source needs custom parsing) to turn binary/markdown into plain text.
  3. Recursive Character Text Splitter node (under the "Document Loaders" category) to chunk the text. A common starting point is a chunk size of 1000 characters with 200 characters of overlap, though you should tune this against your actual documents.
  4. Embeddings node, for example Embeddings OpenAI, configured with your API key credential and a model like text-embedding-3-small.
  5. Vector Store node, for example Qdrant Vector Store, set to "Insert Documents" mode, pointed at your collection.

Here is what the equivalent operation looks like if you were doing it by hand with the Qdrant REST API, which is useful context for understanding what the node is doing for you:

curl -X PUT "http://localhost:6333/collections/docs" \
  -H "Content-Type: application/json" \
  -d '{
    "vectors": {
      "size": 1536,
      "distance": "Cosine"
    }
  }'

The n8n node handles collection creation, batching the embed calls, and the upsert call, but it inherits whatever schema constraints the backend needs. For Qdrant that means a fixed vector size. If your embedding model changes (say you switch from a 1536-dimension OpenAI model to a 768-dimension local model), you'll need a new collection, because most vector databases won't let you mix dimensions in one index. This is the single most common failure people hit the first time they swap embedding providers mid-project: the insert node throws a dimension mismatch error and it looks like a bug in n8n when it's actually a schema issue in the store.

Metadata matters as much as the chunking here. Every vector store node accepts a metadata object alongside each document, and that metadata comes back on every retrieval hit. Attach at minimum a source filename, a URL or path, and a chunk index, so that when your RAG bot answers a question you can show the user where the answer came from. Skipping metadata is the second most common mistake: people get retrieval working, then realize six months in that there's no way to trace an answer back to its source document.

Building the retrieval workflow

Retrieval is the mirror image of ingestion but simpler. A basic "ask a question" workflow looks like:

  1. Webhook or Chat Trigger node to receive the user's question.
  2. Embeddings node (must use the exact same model as ingestion, this is not optional).
  3. Vector Store node in "Retrieve" mode, with a topK parameter (commonly 3 to 8) and an optional metadata filter.
  4. A Basic LLM Chain or Chat Model node that takes the retrieved chunks plus the original question and generates an answer.

The prompt template in step 4 typically looks something like this:

You are a support assistant. Use the following context to answer
the question. If the context does not contain the answer, say
you don't know.

Context:
{{ $json.context }}

Question:
{{ $json.question }}

The {{ $json.context }} expression pulls in whatever the vector store node returned, usually the concatenated pageContent of the top-k results. n8n's expression editor lets you preview this at each node, which is worth doing before you wire up the LLM call, because a silent empty-context bug (for example, a metadata filter that excludes everything) is easy to miss otherwise. Run the retrieve node by itself with "Execute Node" and inspect the JSON output before you chain the LLM call on top of it.

If you want filtered retrieval, most vector store nodes expose a metadata filter field that accepts key-value pairs or, for stores like Qdrant and Pinecone, a more expressive filter object. A typical use case: tag every document at ingestion time with a tenant_id or product field, then filter retrieval by that field so one shared index serves multiple customers or product lines without cross-contamination.

Using n8n vector store nodes with the AI Agent node

The retrieval workflow above is a fixed pipeline: it always fetches from the vector store and always feeds the result to the LLM. For a chatbot that needs to decide whether a question even requires a document lookup (versus a general knowledge question, or a follow-up that doesn't need fresh context), you want the vector store as a tool the agent can choose to call, not a step it always runs.

n8n supports this through "Retrieve as Tool" mode on the vector store node. Set the vector store node to this mode, give it a clear name and description (the description is what the agent's underlying LLM reads to decide when to call it, so be specific, something like "Searches the product documentation for technical details, error messages, and configuration options"), and connect it to the Tool input of an AI Agent node.

The agent workflow then looks like:

  1. Chat Trigger node for the incoming message.
  2. AI Agent node with a system prompt describing its role.
  3. A Chat Model node connected to the agent's model input (this is the reasoning model, separate from the embeddings model).
  4. The Vector Store node in "Retrieve as Tool" mode, connected to the agent's tool input.
  5. Optionally, additional tools (a calculator, an HTTP request tool, another vector store pointed at a different collection) connected the same way.

This pattern is what most production n8n RAG bots actually use, because it lets the agent skip retrieval on small talk and chain multiple tool calls when a question needs, say, both a documentation lookup and a live API call. The tradeoff is latency and cost: every agent turn now involves a reasoning call to decide whether to invoke the tool, on top of the embedding and retrieval calls when it does.

Choosing a vector store backend for n8n

n8n doesn't push you toward one backend, and the right choice depends on what you already run and how much data you're indexing.

  • Simple Vector Store (in-memory): fine for a proof of concept or a workflow that re-indexes a small, static document set on every run. No persistence between executions, no external service to manage.
  • PGVector: a strong default if you already run Postgres, since you get vector search alongside your relational data with one connection. Good for teams that don't want another service to operate.
  • Qdrant: self-hostable in Docker, has a generous free managed tier, and its filtering syntax is expressive. A common pick for teams that want control without giving up managed hosting later.
  • Pinecone: fully managed, no infrastructure to run, straightforward scaling. Reasonable choice if you don't want to operate any database yourself and are comfortable with a managed vendor.
  • Supabase Vector: convenient if your app already uses Supabase for auth and Postgres, since it's the same PGVector extension under Supabase's managed layer.
  • Weaviate / Milvus / MongoDB Atlas Vector Search: each is a solid option if that's already your existing data platform; adding it purely for n8n RAG when you have no other reason to run it is usually more operational overhead than it's worth.

Whatever you pick, index dimension and distance metric (cosine vs. dot product vs. euclidean) need to match what your embeddings model actually produces and what the vector store node is configured for. Mismatches here don't always error loudly, sometimes they just return bad similarity rankings, which is a much harder bug to spot than a hard failure.

Common n8n vector store node pitfalls

A few issues show up repeatedly enough to call out directly.

Re-embedding on every run. If your ingestion workflow runs on a schedule against a document source that hasn't changed, you're paying for embeddings you already have and, depending on the store's upsert behavior, possibly duplicating chunks. Add a step that checks a content hash or last-modified timestamp against stored metadata before running the embed and insert steps, or use an ID scheme (hash of source path plus chunk index) so upserts overwrite rather than duplicate.

Chunk size mismatched to content type. Splitting code documentation with the same 1000-character text splitter you use for prose usually breaks code blocks mid-function. Use a splitter configuration (or a separate ingestion branch) tuned to the content, and consider a Markdown Text Splitter node instead of the generic recursive character splitter when your source is structured.

No error handling on the embeddings call. Embeddings APIs rate-limit and occasionally time out. Wrap the embeddings and vector store nodes in n8n's error handling (the "Continue on Fail" node setting, or a dedicated error workflow) so a single failed batch doesn't silently drop chunks from your index without you noticing.

Forgetting the embeddings model has to match at query time. This bears repeating because it's the most common one-line bug: whatever model embedded your documents at ingestion must be the same model embedding the query at retrieval time. Two different OpenAI embedding models, or an OpenAI model at ingestion against a local Ollama model at query time, will produce vectors that aren't comparable, and similarity search will return near-random results with no error message at all.

Testing retrieval without testing relevance. A workflow that runs without errors isn't the same as a workflow that retrieves the right chunks. Keep a small set of known question-answer pairs and manually check the retrieved context against them whenever you change chunk size, embedding model, or topK. This is the same discipline as testing any search system: measure precision on a fixed test set, don't eyeball a couple of happy-path queries and call it done.

FAQ

Does n8n require a specific vector database? No. n8n supports several vector store integrations (Pinecone, Qdrant, PGVector, Supabase, Weaviate, Milvus, MongoDB Atlas, Zep) plus an in-memory option for testing. You choose the backend based on what you already operate and how much data you're indexing; the node just needs credentials and a collection or index name.

Can I use n8n vector store nodes without the AI Agent node? Yes. You can wire a vector store node directly into a fixed retrieval-then-generate pipeline using a Basic LLM Chain node, without any agent logic. This is simpler and cheaper per query since there's no extra reasoning call to decide whether to search, but it can't skip retrieval for questions that don't need it.

What embeddings models work with n8n vector store nodes? Any embeddings provider n8n has a node for: OpenAI, Cohere, Google Gemini, Azure OpenAI, and self-hosted options through Ollama, among others. The requirement is that the same model and dimension size are used consistently for both ingestion and query, since vectors from different models aren't comparable.

How do I update a document that changed without duplicating it in the vector store? Give each chunk a deterministic ID, typically a hash of the source path combined with the chunk index, and use your vector store's upsert behavior (most n8n vector store nodes support this) so writing with the same ID overwrites the old vector instead of adding a new one. Track a content hash or timestamp in metadata so your ingestion workflow can skip unchanged documents entirely.

Is the Simple Vector Store node usable in production? Generally no, because it holds data in memory for the duration of a workflow execution and doesn't persist across runs or scale past a small document set. It's useful for prototyping a RAG pipeline quickly before committing to a real backend, but production workloads need a persistent store like Qdrant, PGVector, or Pinecone.

How many chunks should I retrieve per query (topK)? There's no universal number; it depends on your chunk size and the LLM's context window. A common starting range is three to eight chunks, tuned by checking whether the retrieved context actually contains the answer for your test question set. Retrieving too few risks missing the answer, retrieving too many adds irrelevant context that can distract the model and increases token cost.

Can one n8n workflow query multiple vector stores? Yes. You can add multiple vector store nodes, each pointed at a different collection or backend, and either run them in parallel and merge results, or expose each as a separate tool to an AI Agent node so the agent picks which one to query based on the question.