How-To

How to Migrate a Vector Database Without Downtime

Move vectors, metadata, and live writes safely with backfill, dual-write validation, gradual cutover, and a tested rollback path.

  • #vector databases
  • #RAG
  • #data migration
  • #zero downtime

A vector database migration can keep an application available throughout the move, but availability alone is not success. The destination must contain the right vectors and metadata, accept every new write, preserve filter behavior, and return results that are good enough for the application. A clean HTTP health check can hide missing records, type coercion, or a serious retrieval regression.

The safer pattern is to run the source and destination in parallel: establish a baseline, build the destination, backfill old data, duplicate new writes, compare real reads, shift traffic gradually, and keep the source recoverable until the rollback window closes. “Without downtime” in this guide means no planned interruption to application reads or accepted writes. It does not promise identical rankings across different index implementations.

Feature statements and official documentation links in this article were checked on 2026-07-24. Exact commands, service limits, consistency behavior, and resource requirements can change, so confirm them for your deployed versions before executing a production migration.

Choose the migration path

The safest transport depends on whether you are staying within one database product, changing products, or changing the embedding space at the same time. The transport moves data; it does not replace dual-write, validation, or rollback planning for writes accepted after the copy begins.

Migration pathBest fitMain advantageMain risk to control
Snapshot or native backup/restoreSame product and compatible versions or topologyCan preserve a prebuilt index and reduce rebuild timeVersion, shard, tenant, and restore-target compatibility
Vendor migration or bulk-import toolSupported source and destination pairHandles batching and may provide resumable progressProvider limits, transformation gaps, and concurrent-write capture
Application-level export and upsertCross-vendor or custom schema mappingFull control over IDs, metadata, and error handlingThrottling, idempotency, and an incomplete change stream
Re-embed into a parallel collectionEmbedding model or preprocessing also changesKeeps the old vector space available for comparisonDatabase and model changes become harder to diagnose together

Use the narrowest path that preserves stable IDs and produces an auditable checkpoint. For example, Pinecone’s official bulk import documentation describes asynchronous imports from object storage into new or empty namespaces, while Weaviate’s official backup documentation describes backup and restore as an option for moving data between environments. These are product-specific capabilities, not interchangeable guarantees.

Inventory schemas and embeddings

Start by defining what “the same data” means. A vector record is more than an array of floats. Your inventory should cover:

  • collection, index, namespace, partition, or tenant boundaries;
  • stable record IDs and the system that owns them;
  • dense and sparse vector names, dimensions, and numeric types;
  • embedding model name, version, preprocessing, and normalization;
  • distance metric or similarity function;
  • metadata field names, types, null behavior, arrays, and nested objects;
  • filterable or indexed metadata fields;
  • deletion markers, expiration rules, and document versions;
  • index, quantization, replication, and consistency settings;
  • query-time transformations, hybrid-search weights, and reranking.

Do not re-embed records merely because you are changing databases. Re-embedding changes the vector space and makes it difficult to tell whether a ranking difference came from the database or the model. If an embedding upgrade is also required, treat it as a separate migration with a separate collection and evaluation.

Capture four baseline artifacts before copying anything: collection counts, a typed metadata sample, representative queries with their exact query vectors and filters, and the source configuration. Qdrant’s official vendor-neutral pre-migration baseline guidance recommends recording exact query vectors, full top-k result lists, filters, dimensions, metrics, and index settings.

Record the source at a named logical checkpoint, such as an update sequence, database transaction ID, or event-stream offset. Wall-clock time alone is weak because writers may have different clocks and operations can arrive out of order.

Define hard gates now: zero missing active IDs, zero cross-tenant leaks, exact agreement on critical metadata, and a measured retrieval-quality threshold. For a deeper scorecard, see how to evaluate RAG retrieval.

Create the destination index

Create a new destination collection instead of pointing migration code at an existing production collection. A clean target makes retries, audits, and deletion of a failed attempt safer.

Translate the schema explicitly. Similar concepts often have different names or constraints across products. Check vector dimensions, distance functions, named or sparse vectors, metadata types, tenant isolation, and filter indexes one field at a time. Preserve stable IDs. If the destination cannot represent a source feature, document the transformation and test its query impact before backfill.

Size the destination for migration load and normal traffic at the same time. Backfill consumes network, CPU, memory, and storage while index construction competes with validation queries and live writes. Provider requirements vary. For example, Qdrant’s current migration and recovery documentation says its streaming migration rebuilds the HNSW index and currently calls for additional target headroom during migration. Treat that as a Qdrant-specific planning input, not a rule for every database.

Before the large copy, run a canary import covering ordinary records, every metadata type, nulls, large records, multiple tenants, dense and sparse vectors, hybrid search, deletes, and ID recreation.

Read each canary back by ID and by filtered search. Confirm that numeric types, arrays, Unicode text, timestamps, and nulls survive the round trip. If the source uses references between objects, preserve their dependency order. Weaviate’s official manual migration guide notes that cursor exports include cross-references and that referenced objects should be restored before objects that point to them.

Keep application traffic on the source. The destination is not production-ready merely because its schema exists.

Backfill historical vectors

Backfill from a reproducible source of truth in deterministic batches. That source might be the existing vector store, but an authoritative document database plus stored embeddings is preferable when available. It gives you another way to detect corruption and rebuild later.

Use stable pagination. An unordered offset scan can skip or repeat records while concurrent updates change the dataset. Prefer an immutable export, cursor, key range, snapshot, or provider migration tool with a documented checkpoint. Qdrant’s official data migration guide states that its migration tool streams live batches and can resume interrupted work, including while new records are being inserted. Other products have different guarantees; verify the chosen tool rather than assuming that “resume” also captures concurrent changes.

Bulk import can be useful for the historical phase but may not be suitable for live changes. Pinecone’s official documentation, for example, distinguishes object-storage import for large datasets from upsert for ongoing writes and requires import namespaces to be new or empty. Build the live-write path separately and wait for the import job’s completed state before treating records as queryable.

Make every batch idempotent: repeating it should converge on the same destination state. Use the stable source ID as the destination primary key and use an update-or-insert operation when the provider supports it. This detail is provider-specific. Milvus, for example, documents that a standard insert does not check for duplicate primary keys and recommends upsert to update existing entities or avoid duplicates in its current insert documentation.

For each batch, record the source cursor range; attempted, accepted, rejected, and retried counts; a checksum over canonical IDs and versions; elapsed time; throttling; and sanitized error categories.

Bound retries and send persistent failures to a repair queue. A migration that retries forever can conceal a schema mismatch while falling farther behind. Throttle based on source health, destination ingestion pressure, and application latency rather than maximizing copy speed.

If you estimate storage or chunk growth before provisioning the target, the RAG chunk size calculator guide explains how overlap and document structure affect record counts.

Dual-write new records

Backfill handles history; dual-write closes the moving gap. Introduce dual-write before the historical copy finishes, or pair a snapshot with a change stream that begins at the same logical checkpoint.

The application should continue treating one durable system as authoritative. Commit the authoritative change, assign a comparable version, enqueue the destination write through an outbox or durable log, apply the same ID and version, retry asynchronously, and expose replication lag and terminal failures.

Avoid a fragile request path that declares the entire user operation failed when the source succeeds but the destination times out. The client may retry, creating duplicates or ambiguous state. A transactional outbox, change-data-capture stream, or durable event log makes the second write recoverable without coupling availability to both databases.

Propagate deletes as versioned operations. Otherwise, a delayed backfill batch can resurrect a record after a newer delete. At the destination, reject an operation whose version is older than the stored version. If the database cannot perform that comparison atomically, enforce it in a single migration writer and test crash recovery.

Monitor lag by sequence, not only by queue length. Ten large operations can matter more than a thousand small ones. Alert on the oldest unreplicated version, terminal failures, and divergence between source and destination counts. Keep enough event history to replay beyond the full rollback window. Qdrant’s official data synchronization overview similarly separates event-driven, batch, and dual-write strategies and notes that dual-write needs background reconciliation to catch divergence.

Compare retrieval results

Counts are necessary but insufficient. Validate three layers separately.

Data integrity: Compare active ID sets, per-tenant counts, vector dimensions, vector checksums where export permits them, and typed metadata. Sample edge cases deliberately. A random sample dominated by ordinary records will miss rare schema failures.

Query behavior: Replay baseline requests with the exact same query vectors, filters, top-k, hybrid weights, and reranker settings. Compare result overlap, rank correlation, latency, filter correctness, and empty-result rate. Do not require score equality across different engines; score scales and approximate-nearest-neighbor implementations may differ.

Application outcomes: Run the downstream RAG or recommendation evaluation. Retrieval overlap can fall while answer quality stays acceptable, or overlap can look high while the one critical document disappears. Use task-specific measures and human review for high-impact cases. The self-hosted evaluation gate provides a pattern for blocking promotion on reproducible checks.

Shadow reads are especially useful: serve the source response to the user, run the same request against the destination asynchronously, and compare sanitized result IDs and timing. Sample traffic to control cost and avoid logging private query text. Separate expected differences, such as approximate ranking ties, from hard failures such as a tenant filter violation.

Do not average away a critical defect. A perfect mean overlap does not compensate for cross-tenant leakage, missing regulated records, or broken deletion. Define those as zero-tolerance gates.

Cut over gradually

Cutover should be a reversible routing change, not a deployment that also modifies embeddings, chunking, query logic, and user interface behavior.

Start with internal traffic or a small, low-risk cohort. Increase destination reads only after a defined observation window passes. Watch errors, tail latency, empty results, filter failures, retrieval metrics, capacity, and replication lag. Keep dual-write active.

Use a stable logical name or routing layer so the application does not require a rushed configuration rollout. Qdrant documents collection aliases as names that can point to collections and says alias changes are atomic, allowing a background-built collection to replace the old one without affecting concurrent requests (official collection-alias documentation). If your database lacks an equivalent atomic alias, implement the switch in a service-discovery or application routing layer that supports rapid reversal.

A practical sequence is:

  • 0% destination reads: validation and shadow traffic only;
  • limited cohort: verify real filters and workload mix;
  • partial traffic: prove capacity and operational response;
  • most traffic: retain a small source control cohort;
  • 100% destination reads: keep writes replicated and the source intact.

Percentages and hold times should reflect traffic volume and risk; there is no universal schedule. A low-volume service may need longer windows to observe rare query shapes. Freeze unrelated schema and embedding changes during the cutover so discrepancies remain diagnosable.

Roll back safely

Write the rollback plan before migration and rehearse it with synthetic records. “Point reads back to the source” is incomplete if the destination has accepted newer writes that never reached the source.

Choose a write strategy that preserves reversibility. During the rollback window, either keep bidirectional compatibility through a single durable event stream or keep the original source receiving authoritative writes. Track the last sequence acknowledged by both systems. A rollback is safe only when you know how every accepted create, update, and delete after cutover returns to the source.

Trigger rollback on explicit gates: integrity or isolation failure, sustained error or latency breach, unrecoverable lag, or application-quality regression. The runbook should name the decision owner, routing operation, cache handling, and verification queries. Do not repurpose the old collection during this period.

After returning reads, replay any missing events, compare counts and critical records, and run the baseline suite again. Preserve migration logs and the failed destination for diagnosis if policy permits. Only decommission the source after the destination has survived the agreed observation window, restore procedures have been tested, event lag is zero, and rollback is no longer required.

Frequently asked questions

Can a vector database be migrated with truly zero downtime?

It can often be migrated without a planned interruption to reads or accepted writes by combining backfill, durable change capture, shadow reads, and gradual routing. That does not mean zero risk or identical search rankings. Define downtime, data-loss tolerance, and retrieval-quality gates before starting.

Should vectors be regenerated during the migration?

Usually not. Copy the existing vectors first so database behavior can be evaluated independently. If the embedding model, preprocessing, or dimension must change, use a separate collection or named-vector path and evaluate it as a second change.

How do I keep new writes in sync during backfill?

Start from a named checkpoint, keep one authoritative write path, and deliver each subsequent create, update, and delete through a durable outbox, change stream, or event log. Use stable IDs and monotonic versions so retries are idempotent and older backfill records cannot overwrite newer changes.

How do I verify that the migration is complete?

Require more than matching counts. Compare active IDs, typed metadata, tenant isolation, vector dimensions, deletion state, and replayed query results. Then run application-level RAG or recommendation evaluations and confirm that replication lag is zero at the cutover checkpoint.

How long should the old vector database be retained?

Retain it through a predefined rollback window long enough to cover representative traffic, delayed events, and a restore rehearsal. The correct duration depends on traffic volume, retention policy, recovery objectives, and operational risk; there is no universal number.

Additional official sources

The following primary documentation was checked on 2026-07-24:

  • Pinecone, Import records: asynchronous bulk import, object-storage format, namespace constraints, and import status.
  • Weaviate, Backups: backup and restore options, live-write behavior during backup, and migration between environments.
  • Qdrant, Keeping your data in sync with Qdrant: event-driven, batch, and dual-write synchronization patterns.

The result is not a single clever command. It is a controlled state transition with two usable systems, measurable equivalence, and an escape route at every stage.