Stack Guide · Supabase + AI
Adding AI to an application usually means adding infrastructure: a vector database for embeddings, a separate embedding generation pipeline, a synchronization layer to keep the vector store in sync with your relational data. Each addition is another system to operate, monitor, and pay for.
Supabase with pgvector collapses that stack. Vector embeddings live in Postgres alongside the data they describe. Row Level Security policies enforce multi-tenant document access at the database layer. Edge Functions handle LLM API calls server-side. Real-time channels stream AI responses to clients.
For the right scale and use case, it's the cleanest AI backend architecture we've used. These are the notes on where it works and where it doesn't.
Building an AI feature on Supabase?
The single-platform architecture has specific advantages. These are the contexts where they matter most.
Supabase gives a TypeScript team one backend for relational data, vector search, authentication, and real-time subscriptions. Adding AI to a Supabase application means adding pgvector and calling LLM APIs from Edge Functions, not adding a separate vector database, a separate embedding service, and a separate auth layer. The single-platform model reduces the operational surface significantly.
This is where Supabase genuinely has an architectural advantage over separate vector databases. Row Level Security policies on the embeddings table mean that a user's vector search automatically filters to their own documents, the database enforces the tenant boundary, not application code. With Pinecone or Qdrant, you either maintain separate namespaces per tenant or write filtering logic that could be misconfigured. RLS is enforced at the database level and can't be bypassed by an application bug.
Supabase's Realtime channels allow an Edge Function calling an LLM to stream tokens back to a connected client through a Postgres channel. This enables streaming UI patterns without a separate WebSocket server. The same Supabase infrastructure that handles your data mutations handles the streaming of AI responses.
For SaaS applications where each user uploads their own documents and searches only their own content, Supabase's combination of auth, storage, and pgvector creates a coherent architecture. User authenticates with Supabase Auth, uploads documents to Supabase Storage, documents get embedded and stored in pgvector with the user's ID, RLS filters search results to that user. The entire lifecycle is in one system.
pgvector is a Postgres extension, not a separate service. The implications of that design decision shape everything about how Supabase + AI architectures work.
Postgres-native vector similarity search
pgvector adds a vector column type and similarity search operators directly to Postgres. You store embeddings in a regular Postgres table alongside the metadata and content they describe. Queries combine vector similarity search with standard SQL WHERE clauses — 'find the 10 most similar documents from the last 30 days that have status = approved' is one query, not a vector search followed by a metadata filter join.
Co-location with the data it describes
With a separate vector database like Pinecone, you maintain two copies of your data: the original records in your relational database and the embeddings in the vector store. They need to stay synchronized. With pgvector, the embedding lives in the same table as the record it describes. There is no synchronization problem because there is only one data store.
Standard Postgres tooling applies
Backups, migrations, point-in-time recovery, connection pooling, read replicas, all the Postgres tooling you already use works with pgvector columns. Running a migration that adds a vector column is the same as running a migration that adds any other column. The operational familiarity is a genuine advantage over learning a new database system's operational model.
pgvector has real scale limits and real constraints. Being honest about them upfront avoids an expensive architecture change later.
High-scale vector search beyond 10 million vectors
pgvector performs well up to roughly 10 million vectors with proper HNSW indexing. Beyond that scale, query latency increases and the ANN (approximate nearest neighbor) accuracy of the HNSW index requires careful tuning. Dedicated vector databases like Pinecone and Qdrant are built specifically for high-scale similarity search and handle 100 million or 1 billion vectors more reliably. If your use case is at that scale, use a dedicated vector store.
When you need ANN index types not in pgvector
pgvector supports HNSW and IVFFlat indexes. Dedicated vector databases offer additional index types optimized for specific recall/latency tradeoffs, filtering patterns, and hardware configurations. If your retrieval requirements demand a specific index architecture that pgvector doesn't support, the right answer is a dedicated vector store rather than working around pgvector's constraints.
Teams not on a Postgres stack
The pgvector advantage is predicated on Postgres already being in your stack. If your primary data store is MongoDB, DynamoDB, or another non-Postgres database, adding Supabase for vectors introduces the synchronization problem that pgvector was supposed to eliminate. In that case, a standalone vector database with your existing data store is a cleaner architecture.
Supabase is our default backend for SaaS AI applications at the scale where pgvector performs well. Here is what the production setup looks like.
For every SaaS application we build with Supabase and AI, we write an RLS policy on the embeddings table on day one, before any data is in it. The policy is simple: users can only SELECT rows where the user_id column matches their auth.uid(). With this policy in place, a vector search executed by any user is automatically restricted to their documents. We have never had a tenant data leakage incident in a system with this architecture.
The default pgvector setup without an index falls back to exact nearest-neighbor search, which scans every row. This is fine for development with a few thousand vectors and catastrophically slow in production with millions. We configure HNSW indexes with ef_construction and m parameters tuned to the expected vector count and query latency requirements before the application goes live.
For LLM API calls (generating embeddings, calling completion endpoints, processing streamed responses), we use Supabase Edge Functions rather than calling APIs from the client. Edge Functions run on Deno, keep API keys server-side, and can be deployed to the same region as the Supabase project. For latency-sensitive embedding generation during document ingestion, co-location of the embedding call and the database write matters.
Three mistakes come up repeatedly in Supabase AI applications. Two of them are fixable. One requires an architecture change.
Using pgvector for billion-scale search
Teams sometimes choose pgvector because they know Postgres and want to avoid learning a new system, even when their scale requirements exceed what pgvector handles well. The result is a vector search that works fine in staging and degrades in production as the vector count grows. Be honest about your scale. If you expect to have more than 10 to 20 million vectors in the first year, start with Pinecone or Qdrant and use Postgres for everything else.
Not setting up proper vector indexes
pgvector without an index does exact nearest-neighbor search. For a table with 100,000 vectors, a single query might take 50 to 100 milliseconds. For a table with 5 million vectors, the same query takes seconds. HNSW and IVFFlat indexes bring query times down to single-digit milliseconds at scale. This is not optional configuration. It is a prerequisite for production query performance.
No RLS on embeddings in multi-tenant apps
The most expensive mistake we see in Supabase AI applications is building the entire system and then discovering that vector search returns results from other tenants. RLS is not automatic on the embeddings table. You have to write the policy. We have seen teams launch without it and then have to retrofit tenant isolation into a live application. Write the RLS policy before you write the first embedding insertion.
Tell us about the application, the document sources, the expected vector count, the multi-tenancy model, and the query patterns. We can give you a specific assessment of whether pgvector fits your scale and how to set up RLS and indexes correctly from day one.