0.0
No release in over 3 years
Vectra provides a unified interface to work with multiple vector database providers including Pinecone, Qdrant, Weaviate, and PostgreSQL with pgvector. Write once, switch providers easily.
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
 Dependencies

Development

~> 1.5
~> 13.0
~> 3.12
~> 1.57
~> 0.22
~> 6.2
~> 3.19
~> 0.9
>= 2.1

Runtime

 Project Readme

Vectra client

Vectra – Unified Ruby client for vector databases

Gem Version CI codecov MIT License

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 install

Quick 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.memory

Architecture 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
Loading

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_vector DSL
  • πŸ” 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

β†’ See full comparison

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:qdrant

This will:

  • Create a pgvector migration (only when provider=pgvector) adding embedding column
  • Generate a model concern (ProductVector) with has_vector :embedding
  • Update the model to include ProductVector
  • Append to config/vectra.yml with 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 MyAuditMiddleware

Production 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, and health_check methods
  • 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 rubocop

Contributing

Bug reports and pull requests welcome at github.com/stokry/vectra.

License

MIT License - see LICENSE file.