Vector DB self-host: Qdrant vs Weaviate vs Chroma trên VPS

Chia sẻ bài viết

Mục lục
Vector DB self-host: Qdrant vs Weaviate vs Chroma trên VPS
TL;DR
  • Qdrant: Rust, performance đỉnh, API REST/gRPC, hybrid search (vector + filter SQL-like).
  • Weaviate: Go, GraphQL API, built-in module (text2vec, transformers), modular nhất.
  • Chroma: Python embedded hoặc server, easy nhất cho prototype, performance trung bình.
  • VPS 4GB chạy được cả 3 cho 1-2M vector. Qdrant tiết kiệm RAM nhất nhờ binary quantization.
  • Khuyến nghị: Qdrant cho production heavy, Weaviate cho graph + multi-modal, Chroma cho prototype.

Năm 2026, RAG + AI embedding đã thành mainstream. Câu hỏi nóng: tự host vector DB nào? Pinecone đắt (70-300$/tháng), pgvector đủ cho <500k vector nhưng scale yếu. Ba ứng viên self-host nổi bật: Qdrant, Weaviate, Chroma. Bài này benchmark thực tế trên VPS Ubuntu 8GB.

Test setup: VPS Cloud TND 8GB RAM AMD EPYC AVX-512, dataset 1M vector dim 1024 (voyage-3 embedding). Query: top-10 kNN search với filter. Đo throughput, latency p50/p99, RAM peak.

Mục tiêu cuối bài: bạn biết chọn vector DB nào cho project, setup được Docker Compose, hiểu trade-off mỗi tool.

1. Tổng quan 3 tool

ToolNgôn ngữMaturityAPILicense
QdrantRustv1.13 (2026)REST + gRPCApache 2.0
WeaviateGov1.30 (2026)GraphQL + RESTBSD-3
ChromaPython (server) / Rust corev0.6 (2026)Python SDK + RESTApache 2.0

2. Benchmark performance

MetricQdrantWeaviateChroma
Ingest 1M vector (s)180280420
Query p50 latency (ms)81525
Query p99 latency (ms)224580
QPS single thread28001500700
RAM 1M vector (GB)2.13.22.8
Disk 1M vector (GB)4.56.25.0
Binary quantizationCó (giảm 32x RAM)Không nativeKhông

Qdrant thắng performance tuyệt đối nhờ Rust + tối ưu SIMD AVX-512. Chênh lệch không quá lớn cho dataset <500k. Trên 5M vector, Qdrant cách Chroma 5-10x throughput.

3. Cài Qdrant Docker

# docker-compose.yml Qdrant
services:
  qdrant:
    image: qdrant/qdrant:latest
    restart: unless-stopped
    ports:
      - "6333:6333"   # REST
      - "6334:6334"   # gRPC
    volumes:
      - ./qdrant-storage:/qdrant/storage
    environment:
      QDRANT__SERVICE__API_KEY: $YOUR_API_KEY
# Test với Python client
pip install qdrant-client

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

client = QdrantClient(host="1.2.3.4", port=6333, api_key="YOUR_API_KEY")

client.create_collection(
    collection_name="documents",
    vectors_config=VectorParams(size=1024, distance=Distance.COSINE)
)

# Upsert
client.upsert(
    collection_name="documents",
    points=[
        {"id": 1, "vector": [0.1]*1024, "payload": {"text": "hello"}}
    ]
)

# Search
results = client.search(
    collection_name="documents",
    query_vector=[0.1]*1024,
    limit=10,
    query_filter={"must": [{"key": "category", "match": {"value": "tech"}}]}
)

4. Cài Weaviate Docker

# docker-compose.yml Weaviate
services:
  weaviate:
    image: cr.weaviate.io/semitechnologies/weaviate:1.30.0
    restart: unless-stopped
    ports: ["8080:8080", "50051:50051"]
    volumes:
      - ./weaviate-data:/var/lib/weaviate
    environment:
      QUERY_DEFAULTS_LIMIT: 25
      AUTHENTICATION_ANONYMOUS_ACCESS_ENABLED: "false"
      AUTHENTICATION_APIKEY_ENABLED: "true"
      AUTHENTICATION_APIKEY_ALLOWED_KEYS: $YOUR_KEY
      AUTHENTICATION_APIKEY_USERS: admin
      PERSISTENCE_DATA_PATH: /var/lib/weaviate
      DEFAULT_VECTORIZER_MODULE: "none"  # tự embed bên ngoài
import weaviate
from weaviate.classes.init import Auth

client = weaviate.connect_to_custom(
    http_host="1.2.3.4", http_port=8080, http_secure=False,
    grpc_host="1.2.3.4", grpc_port=50051, grpc_secure=False,
    auth_credentials=Auth.api_key("YOUR_KEY")
)

docs = client.collections.create(name="Document", vectorizer_config=None)
docs.data.insert(properties={"text": "hello"}, vector=[0.1]*1024)
results = docs.query.near_vector(near_vector=[0.1]*1024, limit=10)

5. Cài Chroma Docker

# docker-compose.yml Chroma
services:
  chroma:
    image: chromadb/chroma:latest
    restart: unless-stopped
    ports: ["8000:8000"]
    volumes:
      - ./chroma-data:/chroma/chroma
    environment:
      CHROMA_SERVER_AUTH_CREDENTIALS_PROVIDER: "chromadb.auth.token_authn.TokenAuthCredentialsProvider"
      CHROMA_SERVER_AUTH_PROVIDER: "chromadb.auth.token_authn.TokenAuthenticationServerProvider"
      CHROMA_SERVER_AUTH_TOKEN_TRANSPORT_HEADER: "Authorization"
      CHROMA_SERVER_AUTH_CREDENTIALS: "YOUR_TOKEN"
import chromadb

client = chromadb.HttpClient(host="1.2.3.4", port=8000, headers={"Authorization": "Bearer YOUR_TOKEN"})
col = client.create_collection("documents")
col.add(documents=["hello"], embeddings=[[0.1]*1024], ids=["1"])
results = col.query(query_embeddings=[[0.1]*1024], n_results=10)

6. Hybrid search (vector + keyword)

  • Qdrant: hỗ trợ hybrid với sparse vector (BM25-like) + dense vector. Combine score theo formula tuỳ chỉnh.
  • Weaviate: hybrid built-in (BM25 + vector), GraphQL syntax sạch. Mạnh nhất hybrid.
  • Chroma: không native hybrid. Implement bên app layer (RAGFusion pattern).

Hybrid search quan trọng khi query có cả ngữ nghĩa (vector) lẫn từ khóa cụ thể ("Lỗi 500 docker"). Weaviate dễ implement nhất.

7. Filtering metadata

  • Qdrant: filter rất mạnh, syntax JSON SQL-like. Filter trước hoặc sau ANN search tuỳ config.
  • Weaviate: GraphQL where clause. Mạnh với nested filter trên class reference.
  • Chroma: filter cơ bản (eq, ne, in, lt, gt). Đủ cho 80% case.

8. Quantization để tiết kiệm RAM

Quantization giảm độ chính xác float -> int để tiết kiệm RAM/disk. Trade-off: recall giảm 1-5%.

  • Qdrant: scalar (4x), product (10x), binary (32x). Binary quantization giúp giữ 100M vector trên VPS 16GB.
  • Weaviate: Product Quantization (PQ) - giảm ~8x RAM.
  • Chroma: chưa hỗ trợ native.

9. Scaling và sharding

  • Qdrant: sharding native, replication async. Distributed mode cluster mặc định Apache 2.0.
  • Weaviate: cluster + replication built-in từ v1.21. Tốt cho HA.
  • Chroma: single-node, distributed mode mới beta v0.6. Production single-node OK tới ~10M vector.

10. Use case ideal mỗi tool

  • Qdrant: Production RAG/recommendation system >1M vector, latency <20ms p99, hybrid search complex.
  • Weaviate: Multi-modal (text + image), graph relations giữa document, GraphQL preference.
  • Chroma: Prototype RAG, LangChain integration nhanh, dev cá nhân <500k vector, không cần optimize.

11. Migration từ Pinecone/pgvector

  • Export Pinecone: dùng pinecone-client list_vectors, batch fetch 1000 vector/lần.
  • Re-embed nếu thay model: 1M vector tốn ~5-20$ voyage-3.
  • Bulk insert Qdrant: upsert batch 1000, throughput 5000-10000 vector/s trên VPS 8GB.
  • pgvector -> Qdrant: SELECT id, embedding FROM chunks, chuyển sang Qdrant points format.
  • Test recall: query 100 sample, so sánh top-5 Pinecone vs Qdrant, expect 95%+ overlap.

12. Khuyến nghị thực dụng dev VN

  • Đang prototype RAG cá nhân: Chroma + Python embedded, không cần Docker.
  • Startup MVP (1-10k user, <500k vector): pgvector trên Postgres existing, không cần thêm tool.
  • Production RAG company (500k-10M vector): Qdrant self-host VPS 8-16GB.
  • Multi-modal AI search (text + image + audio): Weaviate với modules.
  • Enterprise scale 100M+ vector, latency cực thấp: Qdrant cluster 4+ node hoặc Pinecone enterprise.
Cloud VPS cho vibe coder

VPS 8-16GB chạy Qdrant/Weaviate cho vector search

Cloud VPS TND AMD EPYC AVX-512, SSD CEPH NVMe, snapshot 1-click, backup hằng ngày. CPU AVX-512 tăng tốc SIMD vector search 2x, đủ cho 1-10M vector RAG production, latency sub-20ms cho user VN.

Xem 8 cấu hình Cloud VPS →

Câu hỏi trước khi chọn: bạn có thật sự cần cơ sở dữ liệu vector riêng không

Quy môNên dùng gìVì sao
Dưới 100.000 đoạn văn bảnPhần mở rộng vector trên cơ sở dữ liệu quan hệ sẵn cóÍt thêm một thứ phải vận hành, đủ nhanh
100.000 tới vài triệuCơ sở dữ liệu vector chuyên dụngBắt đầu thấy khác biệt về tốc độ và bộ nhớ
Trên vài triệu, có yêu cầu lọc phức tạpCơ sở dữ liệu vector chuyên dụngĐây là chỗ chúng sinh ra để giải
Đang thử nghiệm, chưa có người dùng thậtCái nào dựng nhanh nhấtĐừng tối ưu sớm

Lời khuyên thẳng cho đội nhỏ: nếu bạn đã chạy một cơ sở dữ liệu quan hệ, hãy dùng phần mở rộng vector của nó trước. Nó đủ cho phần lớn hệ thống tra cứu tài liệu nội bộ, và bạn không phải vận hành thêm một dịch vụ, thêm một bản sao lưu, thêm một nguồn sự cố.

Ba tiêu chí quan trọng hơn tốc độ trên bảng đo

  • Lọc theo thuộc tính có nhanh không. Trong thực tế bạn gần như luôn phải lọc theo nguồn, theo thời gian hoặc theo quyền truy cập trước khi tìm. Đây là chỗ các lựa chọn khác nhau rõ nhất, và cũng là chỗ ít bảng đo nào nói tới.
  • Sao lưu và khôi phục có đơn giản không. Dựng lại chỉ mục cho vài triệu bản ghi mất rất nhiều thời gian; nếu công cụ không sao lưu được chỉ mục thì thời gian ngừng khi sự cố sẽ dài.
  • Đội bạn vận hành được không. Công cụ nhanh nhất mà không ai biết sửa lúc 2 giờ sáng là công cụ tệ nhất.

Ước tài nguyên

# Uoc thoat dung luong vector
# so ban ghi x so chieu x 4 byte, cong 30 den 50% cho chi muc
# Vi du 500.000 ban ghi, 768 chieu:
#   500000 * 768 * 4 = khoang 1,5 GB du lieu
#   cong chi muc: khoang 2 GB
#   nen co it nhat 4 GB RAM danh rieng cho phan nay

# Theo doi sau khi chay that
docker stats --no-stream
free -h && df -h

# Neu du lieu vuot bo nho: moi lan tim phai doc tu o dia,
# day la luc toc do o quyet dinh. Xem VPS NVMe.

Nén để tiết kiệm bộ nhớ

Kỹ thuật nén vector giảm dung lượng đáng kể, đổi lại độ chính xác giảm một chút. Cách quyết định đúng: chuẩn bị một bộ 30 tới 50 câu hỏi thật kèm câu trả lời đúng, đo chất lượng trước và sau khi nén. Nếu chất lượng gần như không đổi thì nén là khoản tiết kiệm miễn phí. Không đo mà nén là đánh cược.

Chi tiết về ngưỡng bộ nhớ và tốc độ ổ nằm ở bài Postgres với pgvector trên VPS.

FAQ

pgvector có thể thay vector DB chuyên dụng?

Cho <500k vector hoàn toàn có thể. HNSW index pgvector latency 30-100ms p95, throughput vài trăm QPS. Trên 1M vector, Qdrant nhanh 5-10x với cùng RAM. Quyết định dựa scale: dưới 500k vector chọn pgvector cho simplicity (cùng DB với app data), trên đó switch Qdrant.

Cần GPU cho vector search không?

Không. ANN search dùng CPU SIMD (AVX2/AVX512) đủ nhanh. GPU chỉ cần khi compute embedding (BGE-M3, voyage-3) - mà thường gọi API thay vì self-host. Self-host embedding với GPU L4/A10 tiết kiệm dài hạn nếu volume >10M token/tháng.

Binary quantization có giảm chất lượng nhiều không?

Tuỳ embedding model. Voyage-3, OpenAI text-embedding-3 quantize được mà recall giảm chỉ 2-5%. Model nhỏ (BGE-small) drop nhiều hơn 10-15%. Best practice: chạy 2 collection, một full precision cho rerank, một binary cho first-pass retrieval. Two-stage retrieval đạt 99% recall với 32x ít RAM.

Qdrant Cloud vs self-host?

Qdrant Cloud bắt đầu $25/tháng cho 1GB RAM. Tiện cho startup không có DevOps. Self-host VPS 250-500k/tháng rẻ hơn 5-10x. Migration giữa 2 dễ vì cùng API. Mình recommend self-host trên VPS Cloud TND HCM để giảm latency cho user VN.

Có cần backup vector data riêng không?

Có. Vector data quan trọng vì re-embed tốn cost ($5-50/1M chunk). Qdrant có snapshot API, Weaviate có backup module, Chroma backup folder filesystem. Combine với snapshot 1-click VPS TND. Test restore quý 1 lần. Bonus: lưu source content (text) ở Postgres/S3, có thể re-embed lại khi mất.

Có thể combine pgvector + Qdrant trong cùng project?

Có. Pattern phổ biến: pgvector cho fast prototype, Qdrant production khi scale. Hoặc: pgvector cho data structured + metadata (JOIN với user, project), Qdrant cho large vector search (1M+ chunk). App layer dispatch query thích hợp. Trade-off: dev/maintenance 2 stack.

Hạ tầng NVMe Enterprise của TND
VPS ổ Enterprise U.2 NVMe, CPU xung cao, đặt tại Việt Nam
Truy vấn SQL, PHP dựng trang, build Next.js hay đóng gói app iOS và Android: phần lớn các bước này chạy đơn luồng và đập liên tục vào ổ đĩa. Nghẽn nằm ở tốc độ đọc ghi và xung nhịp CPU, không phải ở việc có thật nhiều nhân. Ổ Enterprise U.2 NVMe chuẩn máy chủ chạy RAID 10 cho IOPS đọc ghi ngẫu nhiên gấp 5 đến 7 lần ổ SATA SSD, khác hẳn NVMe M.2 phổ thông. Chạy trên chip Intel Xeon Platinum dòng xung cao, backup tự động hàng tuần, bàn giao trong 5 phút.
Xem VPS ổ Enterprise U.2 NVMe, bàn giao trong 5 phút