Working with Vector Indexes
Create, manage, and optimize vector indexes for efficient similarity search.
This feature is in alpha
Expect rapid changes, limited features, and possible breaking updates. Share feedback as we refine the experience and expand access.
Vector indexes organize embeddings within a bucket with consistent dimensions and distance metrics. Each index defines how similarity searches are performed across your vectors.
Understanding vector indexes
An index specifies:
- Index Name - Unique identifier within the bucket
- Dimension - Size of vector embeddings (e.g., 1536 for OpenAI)
- Distance Metric - Similarity calculation method (cosine, euclidean, or L2)
- Data Type - Vector format (currently
float32)
Think of an index as a table in a traditional database. It has a schema (dimension) and a query strategy (distance metric).
Creating indexes
Via Dashboard
- Open your vector bucket in the Supabase Dashboard.
- Click Create Index.
- Enter an index name (e.g.,
documents-openai). - Set the dimension matching your embeddings (e.g.,
1536for OpenAI's text-embedding-3-small). - Select the distance metric (
cosine,euclidean, orl2). - Click Create.
Via JavaScript SDK
12345678910111213141516171819import { } from '@supabase/supabase-js'const = ('https://your-project.supabase.co', 'your-service-key')const = ...('embeddings')// Create an indexconst { , } = await .({ : 'documents-openai', : 'float32', : 1536, : 'cosine',})if () { .('Error creating index:', )} else { .('Index created:', )}Choosing the right metric
Most modern embedding models work best with cosine distance:
- OpenAI (text-embedding-3-small, text-embedding-3-large): Cosine
- Cohere (embed-english-v3.0): Cosine
- Hugging Face (sentence-transformers): Cosine
- Google (text-embedding-004): Cosine
- Llama 2 embeddings: Cosine or L2
Tip: Check your embedding model's documentation for the recommended distance metric.
Important: Creating an index with incorrect dimensions will cause insert and query operations to fail.
Managing multiple indexes
Create multiple indexes for different use cases or embedding models:
1234567891011121314151617181920212223242526272829const bucket = supabase.storage.vectors.from('embeddings')// Index for OpenAI embeddingsawait bucket.createIndex({ indexName: 'documents-openai', dimension: 1536, distanceMetric: 'cosine', dataType: 'float32',})// Index for Cohere embeddingsawait bucket.createIndex({ indexName: 'documents-cohere', dimension: 1024, distanceMetric: 'cosine', dataType: 'float32',})// Index for different use caseawait bucket.createIndex({ indexName: 'images-openai', dimension: 1536, distanceMetric: 'cosine', dataType: 'float32',})// List all indexesconst { data: indexes } = await bucket.listIndexes()console.log('All indexes:', indexes)Use cases for multiple indexes
- Different embedding models - Store vectors from OpenAI, Cohere, and local models separately
- Different domains - Maintain separate indexes for documents, images, products, etc.
- A/B testing - Compare different embedding models side-by-side
- Multi-language - Keep language-specific embeddings separate
Listing and inspecting indexes
List all indexes in a bucket
1234567891011const bucket = supabase.storage.vectors.from('embeddings')const { data: indexes, error } = await bucket.listIndexes()if (!error) { indexes?.forEach((index) => { console.log(`Index: ${index.name}`) console.log(` Dimension: ${index.dimension}`) console.log(` Distance: ${index.distanceMetric}`) })}Get index details
12345678const { data: indexDetails, error } = await bucket.getIndex('documents-openai')if (!error && indexDetails) { console.log(`Index: ${indexDetails.name}`) console.log(`Created at: ${indexDetails.createdAt}`) console.log(`Dimension: ${indexDetails.dimension}`) console.log(`Distance metric: ${indexDetails.distanceMetric}`)}Deleting indexes
Delete an index to free storage space:
123456789const bucket = supabase.storage.vectors.from('embeddings')const { error } = await bucket.deleteIndex('documents-openai')if (error) { console.error('Error deleting index:', error)} else { console.log('Index deleted successfully')}Before deleting an index
Warning: Deleting an index is permanent and cannot be undone.
- Backup important data - Export vectors before deletion if needed
- Update applications - Ensure no code references the deleted index
- Check dependencies - Verify no active queries use the index
- Plan the deletion - Do this during low-traffic periods
Immutable properties
Once created, these properties cannot be changed:
- Dimension - Must create new index with different dimension
- Distance metric - Cannot change after creation
- Data type - Currently only
float32supported
Optimizing index performance
12345678910111213141516171819202122// Good - Appropriate batch sizeconst batch = vectors.slice(0, 250)await index.putVectors({ vectors: batch })// Good - Filter metadata before queryconst { data } = await index.queryVectors({ queryVector, topK: 5, filter: { category: 'electronics' },})// Avoid - Single vector insertsfor (const vector of vectors) { await index.putVectors({ vectors: [vector] })}// Avoid - Returning unnecessary dataconst { data } = await index.queryVectors({ queryVector, topK: 1000, // Too many results returnData: true, // Include large embeddings})