Blog post
March 19, 2026

How to connect n8n to Supabase for vector search and RAG workflows

Complete technical tutorial for building RAG systems with n8n and Supabase - from setting up pgvector to implementing document ingestion and query workflows.

n8n workflow diagram showing RAG implementation with Supabase vector database, document embedding generation, and GPT-4 query processing

How to connect n8n to Supabase for vector search and RAG workflows

RAG (Retrieval-Augmented Generation) is how you build AI systems that answer questions using your actual data instead of hallucinating.The technical implementation is straightforward: store document embeddings in a vector database, search for relevant context when a question comes in, inject that context into your LLM prompt.Here's how to build this with n8n and Supabase - the most cost-effective stack for production RAG systems.

Why this stack

n8n: Open source workflow automation. Visual interface, can self-host, handles complex orchestration, free if you run it yourself.Supabase: PostgreSQL with pgvector extension. Familiar SQL database plus vector search. Way cheaper than purpose-built vector databases.OpenAI Embeddings API: Industry standard for converting text to vectors. $0.0001 per 1K tokens.GPT-4: The LLM that generates responses. Could swap for Claude or others.Combined cost for a moderate RAG system: $50-200/month depending on usage. Compare that to Pinecone or Weaviate at $500-2000/month for similar capability.

Prerequisites

You'll need an n8n instance (self-hosted or n8n Cloud), a Supabase project, an OpenAI API key, and basic understanding of embeddings and vector search.If you're new to RAG, the core concept: convert documents to numerical vectors (embeddings), store them, then find documents with vectors similar to your query vector. Those documents become context for your LLM.

Part 1: Supabase setup

Enable pgvector extension

In your Supabase project dashboard, go to Database → Extensions, search for "vector", and enable it. This adds vector data types and similarity search functions to PostgreSQL.

Create the documents table

You need a table to store your documents with their embeddings. The table should have fields for the document content, a vector field for the embedding (dimension 1536 for OpenAI's text-embedding-3-small), optional metadata as JSON, and standard timestamp fields.The vector field type matches your embedding model's output dimension. If using different embedding models, adjust accordingly.

Create the vector similarity search function

Supabase needs a database function that takes a query embedding and returns similar documents. This function uses cosine distance to find the most similar vectors, filters by a similarity threshold, and returns the top matches ordered by relevance.The function returns document ID, content, metadata, and similarity score for each match.

Add an index for performance

Without an index, vector search is slow. With it, searches are fast even with millions of vectors. Use an IVFFlat index optimized for cosine distance operations.The lists parameter should be roughly rows divided by 1000. For 100K documents, use lists equals 100. For 1M documents, use lists equals 1000.

Get your Supabase connection details

You need your Project URL (looks like https://xxxxx.supabase.co) and your Service role key from Settings → API. n8n will use the REST API, so you need the URL and service key.

Part 2: Document ingestion workflow in n8n

This workflow converts documents to embeddings and stores them in Supabase.

Workflow structure

The workflow has six steps: trigger, get documents, split into chunks if needed, generate embeddings via OpenAI API, extract the embedding data, and store in Supabase.

Node 1: Manual Trigger

Add a Manual Trigger node to start. In production, replace this with a webhook or file watcher that automatically processes new documents.

Node 2: Get document content

Use a Function node to provide sample documents, or connect to your actual content source - file uploads, APIs, existing databases, Google Drive, wherever your documents live.Each document should have content and optional metadata like source, category, author, date.

Node 3: Text chunking (optional but recommended)

If documents are long (over 500 tokens or roughly 300-400 words), split them into chunks. Use a Code node that splits text into overlapping chunks of a specified size.Chunking ensures your context stays focused. A 5000-word document might need 10-15 chunks. Each chunk gets its own embedding.

Node 4: Generate embeddings

Add an HTTP Request node that calls the OpenAI embeddings API. Use POST method, authenticate with your API key in the header, and send the document content with the model specification text-embedding-3-small.This returns a numerical vector (array of 1536 numbers) representing the semantic meaning of your text.

Node 5: Extract embedding

The API response is wrapped in metadata. Use a Code node to extract just the embedding array and combine it with your document content and metadata.

Node 6: Store in Supabase

Add an HTTP Request node that POSTs to your Supabase documents table via REST API. Send the content, embedding array, and metadata. Authenticate with your service key in the header.Run the workflow. Check Supabase and you should see documents with embeddings stored.

Part 3: Query workflow (RAG in action)

This workflow takes a user question, finds relevant documents, and generates a response using those documents as context.

Workflow structure

Seven steps: webhook trigger receives question, generate query embedding, search Supabase for similar documents, format retrieved documents as context, inject into prompt, call GPT-4, return response.

Node 1: Webhook trigger

Add a Webhook node that listens for POST requests at a path like /query. Expects JSON body with a question field.

Node 2: Generate query embedding

HTTP Request node calling OpenAI embeddings API, same as ingestion but for the user's question instead of documents. This converts "What does ThinkSwift do?" into a 1536-dimension vector.

Node 3: Extract query embedding

Code node to extract the embedding array from the API response and keep the original question for later steps.

Node 4: Search Supabase

HTTP Request node calling your match_documents database function via Supabase's RPC endpoint. Send the query embedding, a similarity threshold (0.5 is a good starting point), and how many results you want (3-5 typically).This returns the most similar documents from your database - the context that will inform the AI's response.

Node 5: Format context

Code node to combine the retrieved documents into a single context string. Join the document contents with line breaks between them.

Node 6: Call GPT-4 with context

HTTP Request node to OpenAI's chat completions API. Create a system message instructing GPT-4 to answer based on provided context, then a user message containing the context and the original question.Use low temperature (0.3) for factual, consistent responses. Higher temperature (0.7+) for more creative responses.

Node 7: Return response

Extract the generated answer from the API response and return it via the webhook. The user gets an answer grounded in your actual documents, not generic training data.

Testing the complete system

Run the ingestion workflow to populate your vector database with a few test documents. Activate the query workflow webhook. Test with a curl command or Postman sending a question as JSON.You should get a response based on your ingested documents. If the answer is generic or wrong, check that documents were actually stored and that similarity search is returning results.

Production considerations

Chunking strategy matters

Simple word-based chunking works but better approaches include sentence-boundary chunking (don't split mid-sentence), semantic chunking (split at topic boundaries), and recursive chunking (chunk large sections first, then subdivide).For most use cases, 300-500 word chunks with 50-word overlap works fine. Test with your actual documents.

Embedding model choice

text-embedding-3-small is cheap and fast. For better quality consider text-embedding-3-large (2x cost, higher accuracy), Cohere embeddings (competitive pricing, good for multilingual), or Voyage AI (specialized for RAG, excellent quality).Cost vs quality trade-off. Start with 3-small, upgrade if results aren't good enough.

Similarity threshold tuning

We used 0.5 as match threshold. This is arbitrary. Too low includes irrelevant results. Too high excludes relevant results.Test with your data. Start at 0.5, adjust based on result quality. Typical range is 0.4 to 0.7.

Number of results to retrieve

We retrieve 5 documents. This depends on how much context GPT-4 needs (it can handle roughly 8K tokens of context), how fragmented your knowledge is (more fragments equals need more results), and response quality vs cost trade-off (more context equals higher API costs).Start with 3-5, increase if answers lack depth.

Metadata filtering

The Supabase function can filter by metadata - useful for multi-tenant systems or domain-specific queries. Add WHERE clauses that check metadata fields like category, author, date range, or tenant ID.

Caching frequently asked questions

If you get the same questions repeatedly, cache the results. Check cache before doing vector search, store question plus answer pairs with TTL (time to live), dramatically reduces API costs.Simple Redis cache saves 50-80% on API costs for typical use cases.

Monitoring and logging

Log every query including question asked, documents retrieved, answer generated, and user feedback if collected. This data improves your system over time. You'll identify gaps in knowledge, popular questions, and low-quality responses.

Common issues and solutions

Vector search returns irrelevant results

Likely causes are embedding quality (try a better model), chunking strategy (your chunks are too large or poorly segmented), threshold too low (increase match_threshold), or not enough documents (need minimum 50-100 for good results).

Responses hallucinate despite RAG

The LLM is ignoring context. Strengthen system prompt ("Only answer based on provided context"), reduce temperature (0.1-0.3 for factual responses), add explicit instructions ("If context doesn't contain the answer, say I don't have that information"), or use a better model (GPT-4 better than GPT-3.5 for following instructions).

Vector search is slow

You didn't create the index. Go back to Part 1, create the ivfflat index. If you have millions of vectors, consider increasing lists parameter, using HNSW index instead of ivfflat (better for large datasets), or sharding across multiple tables.

Embeddings won't store in Supabase

Common causes include wrong dimension (check your embedding model's output dimension), embedding sent as string instead of array (make sure to parse JSON properly), or Supabase row size limit (unlikely but possible if pgvector plus content exceeds 1GB).

Cost breakdown at scale

Realistic costs for 10,000 documents and 1,000 queries per day:One-time ingestion: 10K documents times 1K tokens average equals 10M tokens. Embedding cost is $1 total.Daily query costs: 1K queries times 1K tokens equals 1M tokens. Embedding cost $0.10 per day equals $3 per month. GPT-4 cost with 500 tokens out times 1K queries equals $15 per day equals $450 per month. Supabase free tier handles this easily.Total monthly: approximately $453Compare to managed RAG solutions charging $1,500 to $3,000 per month for similar volume.

What we actually use in production

This tutorial covers the basics. Our production RAG systems add hybrid search (combine vector search with keyword search for better recall), reranking (use a cross-encoder to rerank retrieved documents before sending to LLM), query decomposition (break complex questions into sub-questions), citation tracking (return which documents were used in the answer), multi-modal RAG (handle images and PDFs, not just text), and evaluation framework (automated testing of RAG quality).But start simple. Get basic RAG working, then add complexity as needed.

Building RAG systems for production? We can help with architecture, implementation, and optimization for your specific use case.

[Talk to us about RAG development]

About ThinkSwift

We're a creative software agency in Melbourne building AI-powered operating systems and RAG-based knowledge systems for established businesses. We use Supabase for most implementations because it's cost-effective, maintainable, and doesn't lock clients into expensive vendor platforms. This tutorial reflects our actual production architecture.

Talk to Penny
Digital Receptionist
Learn More