Migrate from pgvector to Qdrant
What You Need from Postgres
- Connection URL — a standard Postgres connection string
- Table name — the table containing your vector data
Concept Mapping
| pgvector | Qdrant | Notes |
|---|---|---|
| Table | Collection | One-to-one mapping |
| Row | Point | Each row becomes a point |
vector or halfvec column | Vector | Mapped automatically |
| Other columns | Payload | All non-vector columns become payload fields |
vector_cosine_ops | Cosine | The tool creates Cosine by default. pgvector returns distance (1 - similarity). Qdrant returns similarity |
vector_l2_ops | Euclid | Not detected. Set --qdrant.distance-metric explicitly |
vector_ip_ops | Dot | Not detected. Set --qdrant.distance-metric explicitly. pgvector uses negative inner product for ordering; scores will be inverted |
Run the Migration
docker run --net=host --rm -it registry.cloud.qdrant.io/library/qdrant-migration pg \
--pg.url 'postgres://user:password@host:5432/dbname' \
--pg.table 'your_embeddings_table' \
--pg.key-column 'id' \
--qdrant.url 'https://your-instance.cloud.qdrant.io:6334' \
--qdrant.api-key 'your-qdrant-api-key' \
--qdrant.collection 'your-collection'
Selecting Specific Columns
By default, all columns are migrated. Use --pg.columns to select specific ones:
docker run --net=host --rm -it registry.cloud.qdrant.io/library/qdrant-migration pg \
--pg.url 'postgres://user:password@host:5432/dbname' \
--pg.table 'your_embeddings_table' \
--pg.key-column 'id' \
--pg.columns 'id,embedding,title,category' \
--qdrant.url 'https://your-instance.cloud.qdrant.io:6334' \
--qdrant.api-key 'your-qdrant-api-key' \
--qdrant.collection 'your-collection'
All pgvector-Specific Flags
| Flag | Required | Description |
|---|---|---|
--pg.url | Yes | Postgres connection string |
--pg.table | Yes | Table name to migrate |
--pg.key-column | Yes | Column with unique values, which are hashed into point IDs |
--pg.columns | No | Comma-separated columns to migrate (default: all). Must include the key column |
--migration.num-workers | No | Parallel workers (default: number of CPU cores) |
Qdrant-Side Options
| Flag | Default | Description |
|---|---|---|
--qdrant.distance-metric | cosine | Distance metric per vector field (map format, e.g., embedding=euclid). The tool does not read the operator class, so set it for every L2 or IP column |
After Migration: Keeping Postgres and Qdrant in Sync
If you continue using Postgres as your source of truth alongside Qdrant, you’ll need a sync strategy. The Data Synchronization Guide covers three approaches from simple dual-writes to production-grade Change Data Capture.
Next Steps
After migration, verify your data arrived correctly with the Migration Verification Guide.