Skip to main content

Overview

Qdrant is a high-performance vector database with a rich filtering API. VecLabs offers similar performance with added benefits: on-chain verification, 88% lower costs, and true data ownership. This guide maps Qdrant’s API to VecLabs and shows how to migrate your existing collections.

Comparable Performance

1.9ms p50 vs ~4ms on Qdrant

Lower Costs

~8/monthvs8/month vs 25+ for 1M vectors

Decentralized

No single point of failure

Verifiable

Cryptographic proof on Solana

Quick Migration

Python

from qdrant_client import QdrantClient
from qdrant_client.models import Distance, VectorParams, PointStruct

# Initialize client
client = QdrantClient(url="https://your-cluster.qdrant.io:6333")

# Create collection
client.create_collection(
    collection_name="my_collection",
    vectors_config=VectorParams(size=1536, distance=Distance.COSINE)
)

# Insert vectors
client.upsert(
    collection_name="my_collection",
    points=[
        PointStruct(
            id=1,
            vector=[...],
            payload={"text": "hello world"}
        )
    ]
)

# Query
results = client.search(
    collection_name="my_collection",
    query_vector=[...],
    limit=10
)

TypeScript

import { QdrantClient } from '@qdrant/js-client-rest';

const client = new QdrantClient({ url: 'https://your-cluster.qdrant.io:6333' });

await client.createCollection('my_collection', {
  vectors: { size: 1536, distance: 'Cosine' }
});

await client.upsert('my_collection', {
  points: [
    {
      id: 1,
      vector: [...],
      payload: { text: 'hello world' }
    }
  ]
});

const results = await client.search('my_collection', {
  vector: [...],
  limit: 10
});

API Mapping

Client Initialization

QdrantSolVecNotes
QdrantClient(url="...")SolVec(wallet="...")Replace cluster URL with wallet path
api_key="..."N/AAuthentication via Solana wallet
prefer_grpc=TrueN/AVecLabs uses native Rust calls

Collection Management

OperationQdrantSolVec
Createclient.create_collection(name, vectors_config=...)sv.collection(name, dimensions=1536)
Listclient.get_collections()sv.list_collections()
Statsclient.get_collection(name)collection.describe_index_stats()
Deleteclient.delete_collection(name)Not yet implemented

Vector Operations

OperationQdrantSolVec
Insertclient.upsert(collection_name, points=[...])collection.upsert([...])
Searchclient.search(collection_name, query_vector=[...], limit=10)collection.query(vector=[...], top_k=10)
Fetchclient.retrieve(collection_name, ids=[...])collection.fetch(ids=[...])
Deleteclient.delete(collection_name, points_selector=[...])collection.delete(ids=[...])

Key Differences

Data Types

Vector IDs

from qdrant_client.models import PointStruct
import uuid

# Integer IDs
point = PointStruct(id=42, vector=[...], payload={})

# UUID IDs
point = PointStruct(id=uuid.uuid4(), vector=[...], payload={})

Metadata vs Payload

QdrantSolVec
payload={"key": "value"}metadata={"key": "value"}
Supports filtering with operatorsBasic filtering (alpha)
Nested JSON structuresFlat key-value pairs recommended

Distance Metrics

QdrantSolVecNotes
Distance.COSINEmetric="cosine"Default in both
Distance.EUCLIDmetric="euclidean"Supported
Distance.DOTmetric="dot"Supported
Distance.MANHATTANNot supportedUse euclidean instead

Complete Example: RAG System

from qdrant_client import QdrantClient
from qdrant_client.models import Distance, VectorParams, PointStruct, Filter, FieldCondition, MatchValue
from openai import OpenAI

# Initialize
client = QdrantClient(url="https://cluster.qdrant.io:6333", api_key="...")
openai_client = OpenAI()

# Create collection
client.create_collection(
    collection_name="docs",
    vectors_config=VectorParams(size=1536, distance=Distance.COSINE)
)

# Index documents
docs = [
    {"id": 1, "text": "VecLabs is decentralized", "source": "intro.md"},
    {"id": 2, "text": "HNSW provides fast search", "source": "technical.md"},
]

for doc in docs:
    embedding = openai_client.embeddings.create(
        model="text-embedding-3-small",
        input=doc["text"]
    ).data[0].embedding
    
    client.upsert(
        collection_name="docs",
        points=[PointStruct(
            id=doc["id"],
            vector=embedding,
            payload={"text": doc["text"], "source": doc["source"]}
        )]
    )

# Query with filter
query = "What is VecLabs?"
query_embedding = openai_client.embeddings.create(
    model="text-embedding-3-small",
    input=query
).data[0].embedding

results = client.search(
    collection_name="docs",
    query_vector=query_embedding,
    limit=5,
    query_filter=Filter(
        must=[FieldCondition(key="source", match=MatchValue(value="intro.md"))]
    )
)

for result in results:
    print(f"Score: {result.score}, Text: {result.payload['text']}")

Feature Comparison

Filtering

Qdrant has advanced filtering with operators:
Filter(
    must=[
        FieldCondition(key="price", range=Range(gte=100, lte=500)),
        FieldCondition(key="category", match=MatchValue(value="electronics"))
    ]
)
SolVec (Alpha) has basic equality filtering:
filter={"category": "electronics"}  # Exact match only
Advanced filtering (range queries, geo-filtering) is planned for VecLabs v1.0.

Batch Operations

Qdrant supports streaming uploads:
client.upload_collection(
    collection_name="docs",
    vectors=vectors,
    payload=payloads,
    batch_size=1000
)
SolVec batches automatically:
# Just pass all vectors — batching is automatic
collection.upsert(vectors)  # Handles large batches internally

Snapshots & Backups

FeatureQdrantSolVec
Snapshotsclient.create_snapshot()Merkle root on Solana
BackupsManual export/importShadow Drive (encrypted)
Point-in-time recoveryVia snapshotsVia on-chain transaction history

Configuration Mapping

Distance Metrics

from qdrant_client.models import Distance, VectorParams

client.create_collection(
    collection_name="vectors",
    vectors_config=VectorParams(
        size=1536,
        distance=Distance.COSINE  # or EUCLID, DOT, MANHATTAN
    )
)

Collection Settings

SettingQdrantSolVec
Vector sizevectors_config.sizedimensions=1536
Distance metricdistance=Distance.COSINEmetric="cosine"
On-disk payloadon_disk_payload=TrueShadow Drive (alpha)
Replicationreplication_factor=3Solana validators (built-in)
Shardingshard_number=4Not needed (decentralized)

Performance Comparison

Benchmarked on M2 MacBook, 100K vectors, 384 dimensions:
MetricQdrantVecLabs
p50 latency~4ms1.9ms (2.1x faster)
p95 latency~9ms2.8ms (3.2x faster)
p99 latency~15ms4.3ms (3.5x faster)
Monthly cost (1M vectors)$25+$8 (68% cheaper)
Filtering overhead+2-5ms+1ms (basic)
Why VecLabs is faster:
  • Rust core (no GC pauses)
  • HNSW graph in memory
  • Optimized for read-heavy workloads

Migration Checklist

1

Export Qdrant data

from qdrant_client import QdrantClient

client = QdrantClient(url="...")
points, _ = client.scroll(
    collection_name="my_collection",
    limit=10000,
    with_payload=True,
    with_vectors=True
)

# Save to JSON
import json
with open("export.json", "w") as f:
    json.dump([p.dict() for p in points], f)
2

Install SolVec

pip install solvec --pre
3

Set up Solana wallet

solana-keygen new --outfile ~/.config/solana/id.json
solana airdrop 2 --url devnet
4

Import to SolVec

from solvec import SolVec
import json

sv = SolVec(wallet="~/.config/solana/id.json")
collection = sv.collection("my_collection", dimensions=1536)

with open("export.json") as f:
    points = json.load(f)

vectors = [
    {
        "id": str(p["id"]),  # Convert to string
        "values": p["vector"],
        "metadata": p["payload"]
    }
    for p in points
]

collection.upsert(vectors)
print(f"Imported {len(vectors)} vectors")
5

Verify integrity

proof = collection.verify()
print(f"Merkle root: {proof.on_chain_root}")
print(f"Explorer: {proof.solana_explorer_url}")
6

Update application code

Replace client.search() with collection.query()

What’s Not Supported (Yet)

VecLabs is in alpha. These Qdrant features are planned but not yet available:
Qdrant FeatureStatusPlanned
Advanced filtering (range, geo)Not supportedv1.0
Named vectors (multi-vector per point)Not supportedv1.2
Recommendations APINot supportedv1.1
QuantizationNot supportedv1.3
Sparse vectorsNot supportedConsidering

New Capabilities in VecLabs

On-Chain Verification

Qdrant requires trusting their infrastructure. VecLabs provides cryptographic proof:
proof = collection.verify()

print(f"Local Merkle root:    {proof.local_root}")
print(f"On-chain Merkle root: {proof.on_chain_root}")
print(f"Match: {proof.match}")  # True if data integrity is intact

# Anyone can verify this URL
print(proof.solana_explorer_url)

Wallet-Based Ownership

Your vectors are encrypted with your Solana wallet key:
# Only the wallet owner can decrypt these vectors
sv = SolVec(wallet="~/.config/solana/id.json")
collection = sv.collection("private-data")

# VecLabs cannot read this data
collection.upsert([{"id": "secret", "values": [...], "metadata": {"ssn": "..."}}])

Need Help?

Discord Community

Ask questions in #migration-help

Migration Script

Automated Qdrant → SolVec migration tool

API Reference

Full SolVec API documentation

Benchmarks

Detailed performance comparisons

Next Steps

Optimize for Production

Learn best practices for deploying SolVec to mainnet

Build docs developers (and LLMs) love