Vectra client
A unified Ruby client for vector databases.
Write once, switch providers seamlessly.
π Documentation: vectra-docs.netlify.app
Supported Providers
| Provider | Type | Status |
|---|---|---|
| Pinecone | Managed Cloud | β Supported |
| Qdrant | Open Source | β Supported |
| Weaviate | Open Source | β Supported |
| pgvector | PostgreSQL | β Supported |
| Memory | In-Memory | β Testing only |
Installation
gem 'vectra-client'bundle installQuick Start
require 'vectra'
# Initialize client (works with any provider)
client = Vectra::Client.new(
provider: :pinecone,
api_key: ENV['PINECONE_API_KEY'],
environment: 'us-west-4'
)
# Upsert vectors
client.upsert(
vectors: [
{ id: 'doc-1', values: [0.1, 0.2, 0.3], metadata: { title: 'Hello' } },
{ id: 'doc-2', values: [0.4, 0.5, 0.6], metadata: { title: 'World' } }
]
)
# Search (classic API)
results = client.query(vector: [0.1, 0.2, 0.3], top_k: 5)
results.each { |match| puts "#{match.id}: #{match.score}" }
# Search (chainable Query Builder)
results = client
.query('docs')
.vector([0.1, 0.2, 0.3])
.top_k(5)
.with_metadata
.execute
results.each do |match|
puts "#{match.id}: #{match.score}"
end
# Normalize embeddings (for better cosine similarity)
embedding = openai_response['data'][0]['embedding']
normalized = Vectra::Vector.normalize(embedding)
client.upsert(vectors: [{ id: 'doc-1', values: normalized }])
# Delete
client.delete(ids: ['doc-1', 'doc-2'])
# Health check
if client.healthy?
puts "Connection is healthy"
end
# Ping with latency
status = client.ping
puts "Provider: #{status[:provider]}, Latency: #{status[:latency_ms]}ms"
# Hybrid search (semantic + keyword)
# Supported by: Qdrant, Weaviate, Pinecone, pgvector
results = client.hybrid_search(
index: 'docs',
vector: embedding,
text: 'ruby programming',
alpha: 0.7 # 70% semantic, 30% keyword
)
# Text-only search (keyword search without embeddings)
# Supported by: Qdrant, Weaviate, pgvector
results = client.text_search(
index: 'products',
text: 'iPhone 15 Pro',
top_k: 10
)Provider Examples
# Pinecone
client = Vectra.pinecone(api_key: ENV['PINECONE_API_KEY'], environment: 'us-west-4')
# Qdrant (local)
client = Vectra.qdrant(host: 'http://localhost:6333')
# Qdrant (cloud)
client = Vectra.qdrant(host: 'https://your-cluster.qdrant.io', api_key: ENV['QDRANT_API_KEY'])
# Weaviate
client = Vectra.weaviate(
api_key: ENV['WEAVIATE_API_KEY'],
host: 'https://your-weaviate-instance'
)
# pgvector (PostgreSQL)
client = Vectra.pgvector(connection_url: 'postgres://user:pass@localhost/mydb')
# Memory (in-memory, testing only)
client = Vectra.memoryArchitecture Overview
graph TB
A[Vectra Client] --> B[Unified API]
B --> C[Pinecone]
B --> D[Qdrant]
B --> E[Weaviate]
B --> F[pgvector]
B --> G[Memory]
H[Production Patterns] --> I[Circuit Breaker]
H --> J[Rate Limiter]
H --> K[Retry Logic]
H --> L[Instrumentation]
A --> H
style A fill:#05df72
style B fill:#2ee889
style H fill:#04b85e
Features
- π Provider Agnostic - Switch between 5 providers with one line change
- π Production Ready - Ruby 3.2+, 95%+ test coverage, enterprise patterns
- π‘οΈ Resilient - Circuit breaker, rate limiter, retry logic with exponential backoff
- π Observable - Grafana dashboards, Prometheus metrics, 4 instrumentation backends
-
ποΈ Rails Ready - ActiveRecord integration with
has_vectorDSL - π Hybrid Search - Semantic + keyword search across 4 providers
- π§ͺ Testing - Built-in mock provider for easy testing
- β‘ Performance - Connection pooling, caching, async batch operations
π Why Vectra?
| What You Get | Vectra | Others |
|---|---|---|
| Providers | 5 unified | 1 each |
| Production Patterns | β 7 built-in | β Manual |
| Testing | β Mock provider | β External DB |
| Rails | β
has_vector DSL |
β οΈ Manual |
| Observability | β 4 backends | β DIY |
Rails Integration
Quick Start
class Document < ApplicationRecord
include Vectra::ActiveRecord
has_vector :embedding,
provider: :qdrant,
index: 'documents',
dimension: 1536
end
# Auto-indexes on save
doc = Document.create!(title: 'Hello', embedding: [0.1, 0.2, ...])
# Search
Document.vector_search(embedding: query_vector, limit: 10)Rails Generator: vectra:index
Generate everything you need for a model with a single command:
rails generate vectra:index Product embedding dimension:1536 provider:qdrantThis will:
-
Create a pgvector migration (only when
provider=pgvector) addingembeddingcolumn -
Generate a model concern (
ProductVector) withhas_vector :embedding -
Update the model to include
ProductVector -
Append to
config/vectra.ymlwith index metadata (no API keys)
When config/vectra.yml contains exactly one entry, a plain Vectra::Client.new in that Rails app will automatically use that entry's index (and namespace if present) as its defaults, so you can usually omit index: when calling upsert / query / text_search.
Complete Rails Guide
For a complete step-by-step guide including:
- Setting up embeddings (OpenAI, Cohere)
- Processing 1000+ products
- Background jobs
- Hybrid search
- Performance optimization
π Read the complete Rails Integration Guide
Recipes & Patterns
Real-world patterns for common use cases:
- E-Commerce Search - Semantic product search with filters
- Blog Hybrid Search - Combine semantic + keyword matching
- Multi-Tenant SaaS - Namespace isolation per tenant
- RAG Chatbot - Context retrieval for LLMs
- Zero-Downtime Migration - Switch providers safely
- Recommendation Engine - Find similar items
π Browse all Recipes & Patterns
Migration Tool
Migrate vectors between providers with zero downtime:
source_client = Vectra::Client.new(provider: :memory)
target_client = Vectra::Client.new(provider: :qdrant, host: "http://localhost:6333")
migration = Vectra::Migration.new(source_client, target_client)
result = migration.migrate(
source_index: "old-index",
target_index: "new-index",
on_progress: ->(stats) {
puts "Progress: #{stats[:percentage]}% (#{stats[:migrated]}/#{stats[:total]})"
}
)
# Verify migration
verification = migration.verify(
source_index: "old-index",
target_index: "new-index"
)π Read the Migration Tool Guide
Middleware System
Vectra features a powerful Rack-style middleware system that allows you to extend functionality without modifying core code.
Quick Start
# Global middleware (applies to all clients)
Vectra::Client.use Vectra::Middleware::Logging
Vectra::Client.use Vectra::Middleware::Retry, max_attempts: 5
Vectra::Client.use Vectra::Middleware::CostTracker
# Per-client middleware
client = Vectra::Client.new(
provider: :qdrant,
middleware: [
Vectra::Middleware::PIIRedaction,
Vectra::Middleware::Instrumentation
]
)Built-in Middleware
- Logging - Request/response logging with timing
- Retry - Automatic retries with exponential backoff
- Instrumentation - Metrics and monitoring integration
- PIIRedaction - Automatic PII (email, phone, SSN) redaction
- CostTracker - Track API usage costs per operation
- RequestId - Generate unique request IDs for distributed tracing
- DryRun - Log operations without executing (for debugging/testing)
Custom Middleware
class MyAuditMiddleware < Vectra::Middleware::Base
def before(request)
# Called before the operation
AuditLog.create!(action: request.operation, user: Current.user)
end
def after(request, response)
# Called after successful operation
puts "Duration: #{response.metadata[:duration_ms]}ms"
end
def on_error(request, error)
# Called when an error occurs
ErrorTracker.notify(error, context: { operation: request.operation })
end
end
Vectra::Client.use MyAuditMiddlewareProduction Patterns
Vectra includes 7 production-ready patterns out of the box:
- Circuit Breaker - Automatic failover when providers are down
- Rate Limiter - Token bucket algorithm to prevent API throttling
- Retry Logic - Exponential backoff with jitter
- Connection Pooling - Efficient connection management (pgvector)
- Caching - LRU cache with TTL for frequently queried vectors
-
Health Checks -
healthy?,ping, andhealth_checkmethods - Instrumentation - Datadog, New Relic, Sentry, Honeybadger support
Roadmap
High-level roadmap for vectra-client:
-
1.x (near term)
- Reranking middleware built on top of the existing Rack-style middleware stack.
- Additional middleware building blocks (sampling, tracing, score normalization).
- Smoother Rails UX for multi-tenant setups and larger demos (eβcommerce, RAG, recommendations).
-
Mid term
- Additional providers where it makes sense and stays maintainable.
- Deeper documentation and recipes around reranking and hybrid search.
For a more detailed, always-up-to-date version, see the online roadmap: https://vectra-docs.netlify.app/guides/roadmap/
Development
git clone https://github.com/stokry/vectra.git
cd vectra
bundle install
bundle exec rspec
bundle exec rubocopContributing
Bug reports and pull requests welcome at github.com/stokry/vectra.
License
MIT License - see LICENSE file.
