@neureus/vector-db
v0.1.0
Published
Lightning-fast vector database service built for Cloudflare's edge network
Readme
@nexus/vector-db
Production-ready vector database for Cloudflare's edge network, powered by Cloudflare Vectorize with intelligent HNSW fallback. Designed to handle millions of embeddings with sub-50ms search times globally.
Features
🚀 Lightning Fast - Sub-50ms search latency globally with Cloudflare Vectorize 📊 Massive Scale - Support 10M+ vectors per index 🔍 Dual Search Modes - Cloudflare Vectorize primary + HNSW fallback 🎯 Metadata Filtering - Rich filtering and hybrid search capabilities ⚡ Edge Native - Built specifically for Cloudflare Workers, Vectorize, R2, D1, and KV 🛡️ Production Ready - Comprehensive error handling, analytics, and monitoring 🔄 GraphQL API - Full GraphQL schema and resolvers included
Architecture Overview
The vector database uses a tiered architecture for optimal performance:
- Primary: Cloudflare Vectorize - Native vector search service
- Fallback: HNSW Index - In-memory approximate nearest neighbor search
- Storage: R2 + D1 + KV - Multi-layer persistence and caching
Installation
npm install @nexus/vector-db
# or
pnpm add @nexus/vector-dbQuick Start
import { createVectorDB } from '@nexus/vector-db';
// Initialize the vector database with Cloudflare Vectorize
const vectorDB = createVectorDB({
VECTORIZE_INDEX: env.VECTORIZE_INDEX, // Cloudflare Vectorize binding
VECTOR_BUCKET: env.VECTOR_BUCKET, // R2 bucket for backups
VECTOR_KV: env.VECTOR_KV, // KV namespace for caching
VECTOR_DB: env.VECTOR_DB, // D1 database for metadata
ANALYTICS: env.ANALYTICS, // Analytics engine
ENVIRONMENT: 'production',
}, {
vectorize: {
enabled: true, // Use Vectorize as primary
fallbackToHNSW: true, // Enable HNSW fallback
},
});
await vectorDB.initialize();
// Insert a vector
const vectorId = await vectorDB.upsert({
id: 'doc-1',
vector: [0.1, 0.2, 0.3, 0.4, 0.5], // Your embedding vector
metadata: {
title: 'Introduction to AI',
category: 'documentation',
author: 'John Doe',
},
});
// Search for similar vectors
const results = await vectorDB.search({
vector: [0.15, 0.25, 0.35, 0.45, 0.55], // Query vector
topK: 10,
includeMetadata: true,
filter: {
category: 'documentation',
},
});
console.log('Similar documents:', results.matches);Cloudflare Vectorize Integration
Configuration
Add Vectorize binding to your wrangler.toml:
[[vectorize]]
binding = "VECTORIZE_INDEX"
index_name = "nexus-vector-index"Direct Vectorize Access
You can also use the VectorizeClient directly for lower-level operations:
import { VectorizeClient } from '@nexus/vector-db';
const vectorizeClient = new VectorizeClient(env);
// Insert vectors
await vectorizeClient.insert({
id: 'vec-1',
vector: [0.1, 0.2, 0.3],
metadata: { key: 'value' },
});
// Search
const results = await vectorizeClient.search({
vector: [0.15, 0.25, 0.35],
topK: 10,
});
// Get vector by ID
const vector = await vectorizeClient.get('vec-1');
// Delete vectors
await vectorizeClient.delete('vec-1');
// Batch operations
await vectorizeClient.insertBatch(vectors);
await vectorizeClient.deleteBatch(ids);
// Get index info
const info = await vectorizeClient.getIndexInfo();GraphQL API
Full GraphQL schema and resolvers are included:
import { typeDefs, resolvers } from '@nexus/vector-db/graphql';
import { createYoga } from 'graphql-yoga';
const yoga = createYoga({
schema: {
typeDefs,
resolvers,
},
context: ({ request }) => ({
vectorDB: createVectorDB(env),
}),
});
// Query example
const query = `
query SearchVectors($input: VectorSearchInput!) {
searchVectors(input: $input) {
matches {
id
score
metadata
}
totalCount
queryTime
}
}
`;
const result = await yoga.fetch('/graphql', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
query,
variables: {
input: {
vector: [0.1, 0.2, 0.3],
topK: 10,
filter: { category: 'docs' },
},
},
}),
});Available GraphQL Operations
Queries:
searchVectors- Vector similarity searchhybridSearch- Combined vector + keyword searchgetVector- Get single vector by IDgetVectorsBatch- Get multiple vectorsgetIndexStats- Index statisticslistIndices- List all indices
Mutations:
insertVector/insertVectorBatch- Insert vectorsupsertVector/upsertVectorBatch- Upsert vectorsdeleteVector/deleteVectorBatch- Delete vectorscreateIndex- Create new indexdropIndex- Drop indexclearNamespace- Clear namespace
Core Concepts
Vector Entries
A vector entry consists of:
- ID: Unique identifier for the vector
- Vector: Array of numbers (embedding)
- Metadata: Optional key-value pairs for filtering
- Timestamp: Automatic timestamp for tracking
type VectorEntry = {
id: string;
vector: number[];
metadata?: Record<string, any>;
timestamp?: number;
};Similarity Metrics
Supported similarity metrics:
- Cosine (default): Best for normalized vectors
- Dot Product: Fast computation for normalized vectors
- Euclidean: Traditional distance measure
Namespaces
Organize vectors into logical groups:
// Insert into namespace
await vectorDB.upsert(vector, 'my-namespace');
// Search within namespace
const results = await vectorDB.search({
vector: queryVector,
namespace: 'my-namespace',
topK: 5,
});Advanced Usage
Batch Operations
For high-throughput scenarios:
// Batch insert up to 1000 vectors
const vectors = [
{ id: 'doc1', vector: [0.1, 0.2, ...], metadata: { type: 'article' } },
{ id: 'doc2', vector: [0.3, 0.4, ...], metadata: { type: 'blog' } },
// ... more vectors
];
const ids = await vectorDB.upsertBatch({
vectors,
namespace: 'content',
});
console.log(`Inserted ${ids.length} vectors`);Metadata Filtering
Powerful filtering with comparison operators:
const results = await vectorDB.search({
vector: queryVector,
topK: 10,
filter: {
category: 'electronics', // Exact match
price: { $lte: 100 }, // Less than or equal
rating: { $gte: 4.0 }, // Greater than or equal
inStock: true, // Boolean match
tags: ['ai', 'ml'], // Array contains
author: { $ne: 'Anonymous' }, // Not equal
},
});Hybrid Search
Combine vector similarity with keyword matching:
const results = await vectorDB.hybridSearch({
vector: queryVector, // Vector component
query: 'machine learning', // Keyword component
topK: 10,
alpha: 0.7, // 70% vector, 30% keyword
filter: {
category: 'tutorials',
},
});Index Management
// Create a custom index
await vectorDB.createIndex({
name: 'high-dim-index',
dimension: 1536, // OpenAI embedding size
metric: 'cosine',
indexType: 'hnsw',
replicas: 2,
shards: 1,
});
// Get index statistics
const stats = await vectorDB.getIndexStats('high-dim-index');
console.log('Index stats:', stats);
// List all indices
const indices = await vectorDB.listIndices();
console.log('Available indices:', indices);API Reference
VectorDB Methods
upsert(vector, namespace?, indexName?)
Insert or update a single vector.
upsertBatch(batch, indexName?)
Batch insert multiple vectors for better performance.
search(query, indexName?)
Perform vector similarity search.
hybridSearch(query, indexName?)
Combine vector and keyword search.
get(id, namespace?)
Retrieve a vector by ID.
delete(id, namespace?, indexName?)
Delete a vector.
clear(namespace?, indexName?)
Clear all vectors in a namespace.
createIndex(config)
Create a new vector index.
getIndexStats(indexName)
Get statistics for an index.
listIndices()
List all available indices.
dropIndex(indexName)
Delete an index.
Search Parameters
type VectorSearch = {
vector: number[]; // Query vector
topK: number; // Number of results (max 1000)
filter?: Record<string, any>; // Metadata filtering
namespace?: string; // Search namespace
includeMetadata?: boolean; // Include metadata in results
includeValues?: boolean; // Include vector values
minSimilarity?: number; // Minimum similarity threshold
};Performance
Performance Targets
- Search Latency: <50ms P95 globally
- Throughput: 1000+ queries/second
- Scale: 10M+ vectors per index
- Accuracy: >95% recall for similarity search
- Availability: 99.9% uptime with global replication
Caching Strategy
Multi-tier caching for optimal performance:
- KV Cache: Hot vectors and search results (1 hour TTL)
- Vectorize Cache: Built-in Cloudflare caching
- HNSW Memory: In-memory index for fallback
Architecture
Storage Layer
- Cloudflare Vectorize: Native vector search service
- R2: Persistent vector backups with global replication
- KV: Fast metadata caching with edge proximity
- D1: Structured queries and complex filtering
Search Layer
- Vectorize Query: Primary search engine
- HNSW: Hierarchical Navigable Small World fallback
- Bloom Filters: Fast negative lookups
- Batch Processing: Optimized bulk operations
Edge Distribution
- 300+ Locations: Cloudflare's global network
- Automatic Failover: Vectorize → HNSW fallback
- Smart Caching: Multi-tier caching strategy
Use Cases
Retrieval-Augmented Generation (RAG)
// Store knowledge base
const knowledge = [
{
id: 'policy-1',
vector: await generateEmbedding('company vacation policy'),
metadata: {
type: 'policy',
title: 'Vacation Policy',
content: 'Employees get 20 days PTO...',
},
},
];
await vectorDB.upsertBatch({ vectors: knowledge, namespace: 'kb' });
// Query for context
const userQuestion = 'How much vacation time do I get?';
const questionVector = await generateEmbedding(userQuestion);
const context = await vectorDB.search({
vector: questionVector,
namespace: 'kb',
topK: 3,
includeMetadata: true,
});
// Send context to LLM for answer generationSemantic Search
// E-commerce product search
const products = await vectorDB.search({
vector: await generateEmbedding('wireless bluetooth headphones'),
topK: 20,
filter: {
category: 'electronics',
inStock: true,
price: { $lte: 200 },
},
});Content Recommendation
// Recommend similar articles
const similar = await vectorDB.search({
vector: userProfileVector,
topK: 10,
filter: {
published: true,
category: userPreferences.categories,
},
});Configuration
Environment Variables
VECTOR_CACHE_TTL=3600 # Cache TTL in seconds
VECTOR_MAX_BATCH_SIZE=1000 # Maximum batch size
ENVIRONMENT=production # Environment name
DEBUG=false # Enable debug loggingCloudflare Bindings
Required bindings in wrangler.toml:
# Vectorize index
[[vectorize]]
binding = "VECTORIZE_INDEX"
index_name = "nexus-vector-index"
# KV for caching
[[kv_namespaces]]
binding = "VECTOR_KV"
id = "your-vector-kv-id"
# D1 for metadata
[[d1_databases]]
binding = "VECTOR_DB"
database_name = "nexus-vector-db"
# R2 for backups
[[r2_buckets]]
binding = "VECTOR_BUCKET"
bucket_name = "nexus-vectors"
# Analytics
[analytics_engine_datasets]
binding = "ANALYTICS"Testing
Comprehensive test suite included:
# Run all tests
npm test
# Run specific test file
npm test vectorize-client.test.ts
# Run with coverage
npm test -- --coverageMonitoring & Analytics
Built-in analytics track:
- Search latency and throughput
- Cache hit/miss rates
- Vectorize vs HNSW usage
- Error rates and types
- Index utilization
- Storage usage
Error Handling
Comprehensive error types:
import { VectorDBError, VectorNotFoundError, DimensionMismatchError } from '@nexus/vector-db';
try {
await vectorDB.search({ vector: invalidVector, topK: 5 });
} catch (error) {
if (error instanceof DimensionMismatchError) {
console.error('Vector dimension mismatch:', error.message);
} else if (error instanceof VectorNotFoundError) {
console.error('Vector not found:', error.message);
} else if (error instanceof VectorDBError) {
console.error('Vector DB error:', error.code, error.message);
}
}Migration from EdgeVector
If you're migrating from EdgeVector, the API is backward compatible:
// Old EdgeVector code
import { EdgeVectorDB } from '@edge-platform/vectors';
// New Nexus Vector DB (drop-in replacement)
import { VectorDB as EdgeVectorDB } from '@nexus/vector-db';
// Same API works!Contributing
This package is part of the NEIROS Platform. For contributions and issues, see the main repository.
License
MIT License - see LICENSE file for details.
