An embedding model may look like just one component in the retrieval pipeline, but once it hits production, it’s effectively coupled with vector dimensionality, distance functions, text preprocessing, chunking strategies, index parameters, and historical data.
So upgrading from embedding-v1 to embedding-v2 is not as simple as changing a model configuration line. Even if both models output 1024-dimensional vectors, that doesn’t mean they live in the same vector space. When you mix old document vectors with new query vectors, distance scores often lose their original semantic meaning.
A production migration needs to solve four problems:
- How to re-vectorize existing data without blocking online retrieval;
- How to keep newly added and modified data consistent during the migration;
- When it’s safe to switch queries to the new model and index;
- How to roll back quickly if the new model underperforms in production.
Core Principle: Vector Indexes Must Ship Together with the Embedding Version
In production systems, what really needs versioning isn’t just a model_name—it’s a complete Embedding Contract. At minimum, you should track the following fields:
embedding_contract:
model: embedding-v2
model_revision: 2026-08-01
dimension: 1024
distance: cosine
preprocessing_version: normalize-v3
chunking_version: chunk-512-v4
index_version: knowledge-prod-v2
The most commonly overlooked fields here are preprocessing_version and chunking_version. If the model stays the same but tokenization, cleaning, HTML denoising, or chunk boundaries change, historical and new vectors can still drift in unpredictable ways.
Therefore, the model, preprocessing, chunking, and index should be governed as a single release unit.
Approach 1: Blue-Green Vector Indexes—Best Compatibility
The blue-green approach maintains two physical indexes:
knowledge_v1: the current production index;knowledge_v2: the new index built with the new embedding model;knowledge_prod: the logical alias that the application always accesses.
During migration, queries continue to hit knowledge_v1 while knowledge_v2 is built in the background. Once validation passes, the alias is atomically switched to the new index.
Step 1: Create the New Index First—Don’t Overwrite In Place
The new model may change dimensionality or the distance function, so the new index should explicitly configure its own schema.
client.create_collection(
collection_name="knowledge_v2",
vectors_config=VectorParams(
size=1024,
distance=Distance.COSINE,
),
)
This constraint illustrates that treating a “model upgrade” as a new index release is generally safer than modifying in place.
Step 2: Enter Dual Write Mode—Don’t Rebuild Everything First and Then Switch
If background re-embedding takes hours or even days, production data will keep changing during the migration. A single full scan will leave the new index perpetually behind the source data.
The correct sequence is:
- Enable dual writes first;
- New/updated data is written to both v1 and v2;
- Then process historical data in the background;
- Finally, verify that the incremental catch-up is complete.
The pseudocode can stay simple:
def upsert_document(doc):
old_vec = embed_v1(doc.text)
new_vec = embed_v2(doc.text)
write("knowledge_v1", doc.id, old_vec, doc.metadata)
write("knowledge_v2", doc.id, new_vec, doc.metadata)
In a real production environment, you shouldn’t rely on a single HTTP request to guarantee both writes succeed. A more robust approach is to drive both index consumers through a message queue, outbox pattern, or CDC stream, with retry/DLQ handling for failed records.
Step 3: Prevent “Old Snapshot Overwriting New Data” During Background Backfill
This is the most subtle race condition in vector migration.
Suppose document A is scanned by the background job at 10:00, then a user updates it at 10:01. The dual-write path has already written the latest version to v2. If the background task at 10:02 re-embeds the 10:00 stale content and overwrites v2, the new index gets rolled back to old data.
Engineering solutions include:
source_version;updated_at;- Monotonically increasing
sequence; - CDC offset;
- Content hash.
The principle is simple: Backfill must never overwrite data newer than itself.
Deletes and Partial Updates Are Harder Than Upserts
Many migration plans handle upserts but ignore deletes. For example, a record may already be deleted from the new index, but the background scan of the old index recreates it.
For this reason, large-scale production systems are better off treating the primary business database or change log as the Source of Truth, rather than using the old vector database as the sole migration source. A more robust data path looks like this:
Primary Data Source
|
+--> CDC / Event Log --> Embedding v1 Consumer --> Index v1
|
+--> CDC / Event Log --> Embedding v2 Consumer --> Index v2
|
+--> Backfill Job ----------------------------> Index v2
This way, deletes, updates, and restores are all handled with unified event semantics.
Approach 2: Named Vectors—For Databases with Native Multi-Vector Support
If your collection already uses Named Vectors and the version supports it, you can add a new vector field to the same record instead of duplicating the entire collection.
point_id: 10001
payload: {...}
vectors:
embedding_v1: [...]
embedding_v2: [...]
The migration then becomes:
- Add the
embedding_v2vector schema; - New writes generate both v1 and v2;
- Background job backfills v2 for historical points;
- Switch queries from
using=embedding_v1tousing=embedding_v2; - After stability is confirmed, delete the old vector.
The advantage is that payload and point IDs don’t need to be duplicated, and rollback is straightforward. However, this depends on database capabilities and the original collection structure—it’s not a universal approach across all vector databases.
Alias Is the Traffic Switch, Not the Migration Itself
Many teams see that Alias supports atomic switching and assume that having an Alias means the zero-downtime migration is done.
In reality, Alias only solves the final hop of traffic switching. The real complexity lies in data preparation before the switch and validation after it. A recommended release state machine:
BUILDING -> DUAL_WRITE -> BACKFILLING -> CAUGHT_UP -> SHADOW_VERIFY
-> CUTOVER -> OBSERVING -> STABLE
Any stage failure should allow a return to the old index, rather than forcing the migration forward.
Don’t Just Compare Record Counts Before Switching
count(v1) == count(v2) doesn’t prove a successful migration. At minimum, run four layers of checks.
1. Data Integrity
Check total point/document counts, missing IDs, duplicate IDs, source versions, incremental lag over the recent period, and embedding error/DLQ counts.
2. Vector Contract
Verify dimension, distance metric, model revision, preprocessing version, and chunking version in the new index. This metadata should be written into the index itself, not just stored in deployment docs.
3. Offline Retrieval Quality
Don’t compare cosine scores between old and new models directly—score distributions can differ across vector spaces. Instead, use a fixed query set to compare:
- Recall@K;
- MRR / NDCG;
- Top-K overlap;
- Manual acceptance results for critical business queries.
4. Shadow Query
Before the official switch, replicate real requests to v2, logging results only without affecting user responses. Focus on:
- Top-K differences;
- Empty result rate;
- p95/p99 retrieval latency;
- Embedding call failure rate;
- Systematic degradation across specific tenants, languages, or document types.
Incremental Updates: The Index Keeps Aging After Model Migration
Model upgrade is just one large-scale change. In day-to-day operations, source documents are constantly modified. If vectors aren’t updated in sync, retrieval results will gradually drift.
For small datasets, periodic full diffs work. As data grows, scanning the entire corpus becomes expensive—it’s better to switch to CDC, event logs, or an enumerable incremental versioning mechanism.
In other words, Embedding Freshness should be a long-running data pipeline, not a one-off script run before launch.
When This Approach Applies
This migration methodology is especially suited for:
- Switching embedding model providers;
- Model version upgrades that change the vector space;
- Dimensionality changes from 768 to 1024/1536;
- Dense encoder replacement or upgrades;
- Major chunking/preprocessing rule changes;
- Simultaneous upgrades to vector index parameters;
- High sensitivity to search service downtime.
If you only have a small amount of offline data, can tolerate a maintenance window, and can afford a one-time full rebuild, you don’t need to introduce a complex dual-write pipeline.
Common Pitfalls
| Pitfall | Reality |
|---|---|
| Same dimensionality means vectors are interchangeable | Dimensionality is just a tensor shape; it doesn’t mean two models share the same semantic space |
| A full rebuild followed by one final incremental pass is enough | Updates, deletes, and partial modifications keep happening during migration; a “final pass” easily misses events or creates ordering issues |
| Once the Alias switch succeeds, the old index can be deleted immediately | Alias only handles traffic switching; production quality still needs observation, and the old index should be kept for a rollback window |
| Offline Recall alone is sufficient, ignoring online distribution | Real production request distribution may differ from offline datasets; shadow traffic and segmented metrics matter |
| Embedding versioning only tracks the model name | You should also track model revision, dimension, distance, preprocessing, chunking, and index version |
Pre-Launch Checklist
Before switching the production Alias, confirm at least the following:
- Dual writes to old and new indexes have been running stably;
- Backfill is complete and incremental lag has converged;
- Delete/partial update semantics have been validated;
- No continuously growing embedding errors or DLQ backlog;
- New index dimension, distance function, and model version are correct;
- Fixed retrieval set passes quality thresholds;
- Shadow queries show no significant segment-level degradation;
- Alias/routing switch operation has been rehearsed;
- Rollback path and old index retention period are clearly defined;
- Post-switch monitoring covers quality, error rates, and latency—not just resource utilization.
References
- Qdrant — Migrate to a New Embedding Model with Zero Downtime: https://qdrant.tech/documentation/tutorials-operations/embedding-model-migration/
- Qdrant — Incremental Embedding Updates: https://qdrant.tech/documentation/tutorials-operations/incremental-embedding-updates/
- Weaviate — Switching vectorizers: https://docs.weaviate.io/weaviate/tutorials/vectorizer-migration
- Milvus — Manage Aliases: https://milvus.io/docs/manage-aliases.md
- Pinecone — Configure an index, API 2026-04: https://docs.pinecone.io/reference/api/2026-04/control-plane/configure_index