Vector databases comparatif : Pinecone vs Weaviate vs Qdrant vs Milvus
Les bases de données vectorielles sont devenues essentielles pour les applications RAG, la recherche sémantique et les systèmes de recommandation. Mais laquelle choisir ? Ce comparatif analyse les quatre leaders du marché selon des critères concrets.
Pourquoi une base vectorielle ?
Les bases de données traditionnelles (PostgreSQL, MongoDB) stockent des données structurées et cherchent par correspondance exacte. Les bases vectorielles stockent des embeddings (représentations numériques) et cherchent par similarité.
Recherche traditionnelle : "SELECT * FROM docs WHERE title = 'machine learning'"
Recherche vectorielle : "Trouve les documents similaires à ce concept [0.12, -0.34, 0.56, ...]"Cas d'usage typiques
| Application | Besoin | Exemple |
|---|---|---|
| RAG | Retrouver des documents pertinents | Chatbot documentaire |
| Recherche sémantique | Comprendre l'intention | "voiture" trouve "automobile" |
| Recommandation | Similarité utilisateurs/produits | "Vous aimerez aussi..." |
| Détection d'anomalies | Patterns inhabituels | Fraude, intrusion |
| Déduplication | Documents similaires | Clustering de tickets support |
Vue d'ensemble des solutions
| Critère | Pinecone | Weaviate | Qdrant | Milvus |
|---|---|---|---|---|
| Type | Managed SaaS | Open source + Cloud | Open source + Cloud | Open source |
| Licence | Propriétaire | BSD-3 | Apache 2.0 | Apache 2.0 |
| Self-hosted | Non | Oui | Oui | Oui |
| Prix | $$$$ | $$ | $$ | $ |
| Complexité | Très simple | Moyenne | Simple | Complexe |
| Scalabilité | Excellente | Bonne | Excellente | Excellente |
Pinecone : le choix managed
Points forts
Zero ops : Pas d'infrastructure à gérer. Vous créez un index, vous insérez des vecteurs, ça marche.
import pinecone
# Initialisation
pinecone.init(api_key="xxx", environment="us-west1-gcp")
# Créer un index
pinecone.create_index("my-index", dimension=1536, metric="cosine")
# Insérer des vecteurs
index = pinecone.Index("my-index")
index.upsert(vectors=[
("id1", [0.1, 0.2, ...], {"text": "Document 1"}),
("id2", [0.3, 0.4, ...], {"text": "Document 2"})
])
# Recherche
results = index.query(vector=[0.15, 0.25, ...], top_k=5, include_metadata=True)Performance : Latence sub-milliseconde, même sur des milliards de vecteurs.
Intégrations : LangChain, LlamaIndex, Haystack nativement supportés.
Points faibles
Coût : Le plus cher du marché. Peut devenir prohibitif à grande échelle.
Vendor lock-in : Pas de self-hosting possible. Migration complexe.
Filtrage limité : Les filtres métadonnées sont moins flexibles que la concurrence.
Tarifs (janvier 2026)
| Plan | Prix | Inclus |
|---|---|---|
| Starter | Gratuit | 100K vecteurs, 1 index |
| Standard | $70/mois | 1M vecteurs |
| Enterprise | Sur devis | Illimité, SLA |
Coût estimé pour 10M vecteurs : ~$700/mois
Quand choisir Pinecone
- Équipe sans expertise infra
- Time-to-market critique
- Budget confortable
- Besoin de SLA enterprise
Weaviate : l'équilibre features/simplicité
Points forts
Hybrid search : Combine recherche vectorielle et BM25 (keywords) dans une même requête.
import weaviate
client = weaviate.Client("http://localhost:8080")
# Créer une classe (schéma)
client.schema.create_class({
"class": "Document",
"vectorizer": "text2vec-openai",
"properties": [
{"name": "text", "dataType": ["text"]},
{"name": "category", "dataType": ["string"]}
]
})
# Insérer avec vectorisation automatique
client.data_object.create({
"text": "Machine learning is a subset of AI",
"category": "tech"
}, "Document")
# Recherche hybride
result = client.query.get("Document", ["text", "category"]).with_hybrid(
query="artificial intelligence",
alpha=0.5 # 0.5 = 50% semantic, 50% keyword
).with_limit(5).do()Vectorisation intégrée : Connecteurs OpenAI, Cohere, HuggingFace pour vectoriser à l'insertion.
GraphQL API : API expressive pour des requêtes complexes.
Modules : Question answering, summarization, classification intégrés.
Points faibles
RAM hungry : Consomme beaucoup de mémoire, surtout avec les modules activés.
Complexité schéma : La définition des classes peut être verbeuse.
Performances filtres : Le filtrage sur métadonnées peut dégrader les performances.
Déploiement
# docker-compose.yaml
services:
weaviate:
image: semitechnologies/weaviate:1.24.0
ports:
- "8080:8080"
environment:
QUERY_DEFAULTS_LIMIT: 25
AUTHENTICATION_ANONYMOUS_ACCESS_ENABLED: 'true'
PERSISTENCE_DATA_PATH: '/var/lib/weaviate'
DEFAULT_VECTORIZER_MODULE: 'text2vec-openai'
ENABLE_MODULES: 'text2vec-openai,generative-openai'
OPENAI_APIKEY: ${OPENAI_API_KEY}
volumes:
- weaviate_data:/var/lib/weaviateTarifs Weaviate Cloud
| Plan | Prix | Inclus |
|---|---|---|
| Sandbox | Gratuit | 14 jours, test |
| Serverless | $25/mois + usage | Pay-as-you-go |
| Enterprise | Sur devis | Dedicated, SLA |
Coût estimé pour 10M vecteurs : ~$150-300/mois (self-hosted) ou ~$400/mois (cloud)
Quand choisir Weaviate
- Besoin de recherche hybride
- Vectorisation automatique souhaitée
- GraphQL préféré
- Modules AI intégrés utiles
Qdrant : performance et simplicité
Points forts
Performance : Écrit en Rust, optimisé pour la vitesse. Excellent ratio performance/ressources.
from qdrant_client import QdrantClient
from qdrant_client.models import Distance, VectorParams, PointStruct
client = QdrantClient("localhost", port=6333)
# Créer une collection
client.create_collection(
collection_name="documents",
vectors_config=VectorParams(size=1536, distance=Distance.COSINE)
)
# Insérer des points
client.upsert(
collection_name="documents",
points=[
PointStruct(
id=1,
vector=[0.1, 0.2, ...],
payload={"text": "Document 1", "category": "tech"}
),
PointStruct(
id=2,
vector=[0.3, 0.4, ...],
payload={"text": "Document 2", "category": "science"}
)
]
)
# Recherche avec filtres
results = client.search(
collection_name="documents",
query_vector=[0.15, 0.25, ...],
query_filter={
"must": [{"key": "category", "match": {"value": "tech"}}]
},
limit=5
)Filtrage puissant : Filtres complexes sans dégradation de performance significative.
API simple : REST et gRPC, client Python intuitif.
Quantization : Compression des vecteurs pour réduire la mémoire (scalar, product).
Points faibles
Pas de vectorisation : Vous devez fournir les embeddings.
Moins de modules : Pas d'intégrations AI natives comme Weaviate.
Documentation : Moins fournie que la concurrence (s'améliore).
Déploiement
# docker-compose.yaml
services:
qdrant:
image: qdrant/qdrant:v1.8.0
ports:
- "6333:6333"
- "6334:6334" # gRPC
volumes:
- qdrant_storage:/qdrant/storage
environment:
QDRANT__SERVICE__GRPC_PORT: 6334Tarifs Qdrant Cloud
| Plan | Prix | Inclus |
|---|---|---|
| Free | $0 | 1GB storage |
| Starter | $25/mois | 4GB storage |
| Scale | $0.05/GB/mois | Pay-as-you-go |
Coût estimé pour 10M vecteurs : ~$50-100/mois (self-hosted) ou ~$200/mois (cloud)
Quand choisir Qdrant
- Performance critique
- Filtrage complexe nécessaire
- Ressources limitées (edge, IoT)
- Préférence pour la simplicité
Milvus : le choix enterprise
Points forts
Scalabilité massive : Conçu pour des milliards de vecteurs, architecture distribuée native.
from pymilvus import connections, Collection, FieldSchema, CollectionSchema, DataType
# Connexion
connections.connect("default", host="localhost", port="19530")
# Définir le schéma
fields = [
FieldSchema(name="id", dtype=DataType.INT64, is_primary=True),
FieldSchema(name="embedding", dtype=DataType.FLOAT_VECTOR, dim=1536),
FieldSchema(name="text", dtype=DataType.VARCHAR, max_length=1000)
]
schema = CollectionSchema(fields, description="Documents")
# Créer la collection
collection = Collection("documents", schema)
# Créer un index
collection.create_index(
field_name="embedding",
index_params={
"metric_type": "COSINE",
"index_type": "IVF_FLAT",
"params": {"nlist": 1024}
}
)
# Insérer
collection.insert([
[1, 2], # ids
[[0.1, 0.2, ...], [0.3, 0.4, ...]], # embeddings
["Doc 1", "Doc 2"] # texts
])
# Charger en mémoire et rechercher
collection.load()
results = collection.search(
data=[[0.15, 0.25, ...]],
anns_field="embedding",
param={"metric_type": "COSINE", "params": {"nprobe": 10}},
limit=5
)GPU support : Accélération GPU pour l'indexation et la recherche.
Index variés : HNSW, IVF, DiskANN, etc. selon vos besoins.
Partitioning : Sharding automatique des données.
Points faibles
Complexité : Courbe d'apprentissage importante, nombreux composants.
Ressources : Nécessite etcd, MinIO, Pulsar en production (ou Milvus Lite pour dev).
Overhead opérationnel : Maintenance non triviale.
Architecture production
# Milvus cluster simplifié
services:
etcd:
image: quay.io/coreos/etcd:v3.5.0
minio:
image: minio/minio:RELEASE.2023-03-20T20-16-18Z
milvus:
image: milvusdb/milvus:v2.3.0
depends_on:
- etcd
- minio
environment:
ETCD_ENDPOINTS: etcd:2379
MINIO_ADDRESS: minio:9000Tarifs Zilliz Cloud (Milvus managed)
| Plan | Prix | Inclus |
|---|---|---|
| Free | $0 | 2 CU, limité |
| Standard | $0.16/CU/heure | Pay-as-you-go |
| Enterprise | Sur devis | Dedicated |
Coût estimé pour 10M vecteurs : ~$100-200/mois (self-hosted) ou ~$500/mois (Zilliz)
Quand choisir Milvus
- Échelle massive (milliards de vecteurs)
- Équipe ops expérimentée
- GPU disponible
- Contrôle total requis
Benchmark comparatif
Test : 1M vecteurs, dimension 1536
| Métrique | Pinecone | Weaviate | Qdrant | Milvus |
|---|---|---|---|---|
| Insertion (vecs/s) | 1,000 | 800 | 1,500 | 2,000 |
| Recherche latence P50 | 5ms | 12ms | 8ms | 10ms |
| Recherche latence P99 | 15ms | 45ms | 25ms | 35ms |
| RAM utilisée | N/A | 8GB | 4GB | 6GB |
| Recall@10 | 0.98 | 0.97 | 0.98 | 0.97 |
Tests sur hardware comparable, HNSW index, sans filtres
Avec filtres métadonnées
| Métrique | Pinecone | Weaviate | Qdrant | Milvus |
|---|---|---|---|---|
| Latence P50 | 8ms | 35ms | 12ms | 18ms |
| Latence P99 | 25ms | 120ms | 40ms | 60ms |
Observation : Qdrant excelle sur le filtrage, Weaviate montre des dégradations notables.
Guide de choix
Arbre de décision
Besoin de vector DB
│
┌────────────┴────────────┐
│ │
Self-hosted ? Managed OK ?
│ │
┌─────────┴─────────┐ │
│ │ │
Équipe ops ? Simplicité ? ┌────┴────┐
│ │ │ │
▼ ▼ │ │
Milvus Qdrant Budget ? Features ?
│ │
▼ ▼
Qdrant Weaviate
Cloud Cloud
│
│
Pinecone
(budget élevé)Matrice de recommandation
| Profil | Recommandation | Raison |
|---|---|---|
| Startup MVP | Qdrant Cloud | Simple, économique |
| Scale-up RAG | Weaviate | Hybrid search, modules |
| Enterprise critique | Pinecone | SLA, zero ops |
| Big data IA | Milvus | Scalabilité, GPU |
| Edge/IoT | Qdrant | Léger, performant |
Migration entre solutions
Export/Import pattern
# Export depuis Weaviate
def export_weaviate(client, class_name):
result = client.query.get(class_name, ["_additional { id vector }"]).do()
return [(obj["_additional"]["id"], obj["_additional"]["vector"])
for obj in result["data"]["Get"][class_name]]
# Import vers Qdrant
def import_qdrant(client, collection_name, data):
points = [
PointStruct(id=idx, vector=vec)
for idx, (_, vec) in enumerate(data)
]
client.upsert(collection_name=collection_name, points=points)Conseils migration
- Testez avant : Créez un environnement de test avec un sous-ensemble
- Validez les résultats : Comparez les résultats de recherche avant/après
- Migration progressive : Double-write pendant la transition
- Monitoring : Surveillez les latences et le recall
Conclusion
Il n'y a pas de "meilleure" base vectorielle universelle :
- Pinecone : Quand le time-to-market et le SLA priment sur le coût
- Weaviate : Quand vous voulez des features IA intégrées et la recherche hybride
- Qdrant : Quand la performance et la simplicité sont prioritaires
- Milvus : Quand vous avez des milliards de vecteurs et une équipe ops solide
Pour la plupart des projets RAG en 2026, Qdrant offre le meilleur compromis performance/simplicité/coût. Commencez avec Qdrant Cloud ou self-hosted, et migrez vers Milvus si vous atteignez l'échelle du milliard de vecteurs.
Pour implémenter votre RAG : RAG en production : architecture simple qui fonctionne vraiment
Pour comprendre les échecs RAG : Pourquoi votre RAG échoue (et comment le corriger)