Supabase AI Guide 2025: Build RAG Apps with pgvector & Edge Functions
A practical guide to using Supabase as your full-stack AI backend — vector storage with pgvector, similarity search in SQL, and serverless AI inference via Edge Functions.
What Is Supabase?
Supabase is an open-source Firebase alternative built on PostgreSQL. It gives you a managed Postgres database, auto-generated REST and GraphQL APIs, authentication, file storage, and serverless edge functions — all with a generous free tier and a self-hostable option.
For AI applications, Supabase is particularly compelling because it ships pgvector as a first-class extension. This means your embeddings, your relational data, and your user records all live in the same Postgres database. No separate vector store to provision, sync, or pay for separately.
Browse the MCP Directory for Supabase MCP servers that let AI agents query your database directly.
Enabling pgvector
pgvector adds a vector column type and vector operators to PostgreSQL. Enable it with a single SQL statement in the Supabase SQL Editor:
-- Enable the pgvector extension CREATE EXTENSION IF NOT EXISTS vector; -- Create a table with a vector column -- 1536 dimensions = OpenAI text-embedding-ada-002 -- 3072 dimensions = OpenAI text-embedding-3-large CREATE TABLE documents ( id bigserial PRIMARY KEY, content text, embedding vector(1536), metadata jsonb ); -- Create an index for fast approximate search CREATE INDEX ON documents USING ivfflat (embedding vector_cosine_ops) WITH (lists = 100);
You can also enable pgvector from the Supabase dashboard under Database > Extensions. Search for "vector" and toggle it on.
Storing and Querying Embeddings
pgvector supports three distance operators: <-> (L2/Euclidean), <=> (cosine), and <#> (inner product/negative). Cosine similarity is the standard for text embeddings.
similarity_search.sql
-- Find 5 most similar documents to a query vector -- Replace '[0.1, 0.2, ...]' with your actual embedding array SELECT id, content, 1 - (embedding <=> '[0.1, 0.2, ...]'::vector) AS similarity FROM documents ORDER BY embedding <=> '[0.1, 0.2, ...]'::vector LIMIT 5;
The IVFFlat index speeds up approximate nearest neighbor (ANN) searches. For smaller datasets (<100k rows) you can skip the index and do exact search — pgvector will use a sequential scan.
TypeScript Quickstart: Generate, Store, Query
A complete end-to-end example using @supabase/supabase-js and the OpenAI SDK:
rag-pipeline.ts
import { createClient } from '@supabase/supabase-js';
import OpenAI from 'openai';
const supabase = createClient(
process.env.SUPABASE_URL!,
process.env.SUPABASE_SERVICE_ROLE_KEY!
);
const openai = new OpenAI();
// 1. Generate embedding
async function embed(text: string): Promise<number[]> {
const res = await openai.embeddings.create({
model: 'text-embedding-3-small',
input: text,
});
return res.data[0].embedding;
}
// 2. Store document + embedding
async function storeDoc(content: string) {
const embedding = await embed(content);
await supabase.from('documents').insert({
content,
embedding: JSON.stringify(embedding),
});
}
// 3. Query similar documents
async function search(query: string, topK = 5) {
const embedding = await embed(query);
const { data } = await supabase.rpc('match_documents', {
query_embedding: embedding,
match_count: topK,
});
return data;
} Use a Postgres function for similarity search — calling supabase.rpc('match_documents', ...) keeps the vector math server-side and avoids shipping the full table over the wire. Create the function via the SQL Editor.
Supabase Edge Functions for AI
Supabase Edge Functions are serverless Deno functions deployed globally. Use them to call OpenAI or Anthropic APIs without exposing your API keys to the client:
supabase/functions/chat/index.ts
import Anthropic from 'npm:@anthropic-ai/sdk';
const client = new Anthropic();
Deno.serve(async (req) => {
const { prompt } = await req.json();
const message = await client.messages.create({
model: 'claude-sonnet-4-5',
max_tokens: 1024,
messages: [{ role: 'user', content: prompt }],
});
return new Response(
JSON.stringify({ response: message.content[0].text }),
{ headers: { 'Content-Type': 'application/json' } }
);
});
Deploy with supabase functions deploy chat. Set your Anthropic API key as a secret: supabase secrets set ANTHROPIC_API_KEY=sk-ant-...
Supabase Vector (LlamaIndex & LangChain)
Supabase Vector provides official adapters for both major RAG frameworks:
# LangChain
from langchain_community.vectorstores import SupabaseVectorStore
from langchain_openai import OpenAIEmbeddings
store = SupabaseVectorStore(
client=supabase_client,
embedding=OpenAIEmbeddings(),
table_name="documents",
query_name="match_documents",
)
docs = store.similarity_search("What is pgvector?", k=3)
# LlamaIndex
from llama_index.vector_stores.supabase import SupabaseVectorStore
vector_store = SupabaseVectorStore(
postgres_connection_string="postgresql://...",
collection_name="documents",
) Also see: LlamaIndex guide · LangChain guide
Supabase vs Firebase vs Neon vs PlanetScale for AI
| Platform | Database | Vector support | Best for |
|---|---|---|---|
| Supabase | PostgreSQL | pgvector built-in | Full-stack AI + auth + storage |
| Firebase | Firestore (NoSQL) | No native vector | Mobile apps, real-time sync |
| Neon | PostgreSQL (serverless) | pgvector extension | Serverless Postgres, branching |
| PlanetScale | MySQL (Vitess) | No pgvector | High-scale MySQL workloads |
Also see: Pinecone guide · Qdrant guide · OpenAI API guide · Anthropic API guide
Track AI API Status
Supabase incidents can break your RAG pipeline. Prismix monitors OpenAI, Anthropic, and other AI API statuses in real time and alerts you when something goes down.
Check AI API Status →