Supabase
Open-source Firebase alternative built on PostgreSQL. Store vectors with pgvector, run AI inference on Edge Functions, and build semantic search applications.
Why Supabase for AI (2025)
Supabase combines PostgreSQL, authentication, storage, and Edge Functions into one platform. With native pgvector support, you can build RAG applications without a separate vector database.
Core Features
- pgvector: Store and query embeddings in PostgreSQL.
- Edge Functions: Serverless Deno functions for AI inference.
- Vector Buckets: S3-backed storage for millions of vectors.
- AI Assistant: Natural language SQL and schema help.
AI Integrations
- OpenAI: Generate embeddings and chat completions.
- Hugging Face: Use open-source models.
- Built-in Inference: Generate embeddings in Edge Functions.
- AI Agents: Let agents read schemas and run queries.
Setting Up pgvector
Enable the vector extension and create a table to store embeddings.
-- Enable pgvector extension
create extension if not exists vector;
-- Create a table for documents with embeddings
create table documents (
id bigserial primary key,
content text not null,
embedding vector(1536), -- OpenAI text-embedding-3-small dimension
metadata jsonb,
created_at timestamp with time zone default now()
);
-- Create an index for faster similarity search
create index on documents using ivfflat (embedding vector_cosine_ops)
with (lists = 100);
-- Or use HNSW index for better performance
create index on documents using hnsw (embedding vector_cosine_ops);
Generating Embeddings
Use OpenAI or Supabase's built-in inference to generate embeddings.
Python with OpenAI
from openai import OpenAI
from supabase import create_client
openai = OpenAI()
supabase = create_client("YOUR_SUPABASE_URL", "YOUR_SUPABASE_KEY")
def embed_and_store(content: str, metadata: dict = None):
# Generate embedding
response = openai.embeddings.create(
model="text-embedding-3-small",
input=content
)
embedding = response.data[0].embedding
# Store in Supabase
supabase.table("documents").insert({
"content": content,
"embedding": embedding,
"metadata": metadata
}).execute()
# Example usage
embed_and_store("Supabase is great for AI applications", {"source": "docs"})
Edge Function (Built-in Inference)
import { serve } from "https://deno.land/std@0.168.0/http/server.ts"
import { createClient } from "https://esm.sh/@supabase/supabase-js@2"
serve(async (req) => {
const { content } = await req.json()
const supabase = createClient(
Deno.env.get('SUPABASE_URL')!,
Deno.env.get('SUPABASE_SERVICE_ROLE_KEY')!
)
// Generate embedding using Supabase AI
const { data: embedding } = await supabase.ai.embeddings.create({
model: 'gte-small',
input: content,
})
// Store in database
await supabase.from('documents').insert({
content,
embedding: embedding[0].embedding
})
return new Response(JSON.stringify({ success: true }))
})
Semantic Search Query
Create a function to find similar documents using cosine distance.
-- Create a similarity search function
create or replace function match_documents (
query_embedding vector(1536),
match_threshold float default 0.7,
match_count int default 5
)
returns table (
id bigint,
content text,
metadata jsonb,
similarity float
)
language sql stable
as $$
select
id,
content,
metadata,
1 - (embedding <=> query_embedding) as similarity
from documents
where 1 - (embedding <=> query_embedding) > match_threshold
order by embedding <=> query_embedding
limit match_count;
$$;
Calling from Python
def semantic_search(query: str, top_k: int = 5):
# Generate query embedding
response = openai.embeddings.create(
model="text-embedding-3-small",
input=query
)
query_embedding = response.data[0].embedding
# Search in Supabase
results = supabase.rpc(
"match_documents",
{
"query_embedding": query_embedding,
"match_threshold": 0.7,
"match_count": top_k
}
).execute()
return results.data
# Example
docs = semantic_search("How does Supabase work with AI?")
for doc in docs:
print(f"[{doc['similarity']:.2f}] {doc['content']}")
RAG with Supabase + OpenAI
Complete Retrieval-Augmented Generation pattern using Supabase as the vector store.
def rag_query(question: str):
# 1. Retrieve relevant documents
docs = semantic_search(question, top_k=3)
# 2. Build context from retrieved documents
context = "\n\n".join([d["content"] for d in docs])
# 3. Generate answer with context
response = openai.chat.completions.create(
model="gpt-4o-mini",
messages=[
{
"role": "system",
"content": f"""Answer the question based on the following context:
{context}
If the context doesn't contain relevant information, say so."""
},
{"role": "user", "content": question}
]
)
return {
"answer": response.choices[0].message.content,
"sources": [d["content"][:100] + "..." for d in docs]
}
# Example
result = rag_query("What are the benefits of using Supabase for AI?")
print(result["answer"])
Supabase vs. Dedicated Vector DBs
| Feature | Supabase + pgvector | Pinecone / Weaviate |
|---|---|---|
| Setup | Already integrated | Separate service |
| Relational + Vector | Same database | Requires sync |
| Scale (vectors) | Millions (Vector Buckets) | Billions+ |
| Cost | Free tier included | Usage-based |
| Auth + Storage | Built-in | Not included |
Use Cases
AI Chatbots
RAG-powered chat with your own documents.
Semantic Search
Find similar products, articles, or users.
Recommendations
Personalized content based on embeddings.