You need to reindex a ten-million-chunk corpus with a new embedding model. How do you do it without downtime?
Build a shadow index beside the live one, dual-write from a recorded change-feed watermark so it never falls behind, verify on reconciliation counts plus a gold set and shadowed production queries, then cut over by moving an alias and keep the old index writable long enough to roll back.
What the interviewer is scoring
- Whether the application resolves an alias rather than an index name, which is what makes cutover atomic at all
- Does the candidate handle the corpus continuing to change during a build that takes hours or days
- That verification goes beyond row counts to retrieval quality on a gold set and diffed production queries
- Whether rollback is a real path, meaning the old index is still receiving writes after cutover
- Can the candidate name the resource cost of holding two indexes and what it forces
Answer
Reindexing is a migration, not a maintenance job
A rebuild is required whenever something upstream of the vectors changes: a new embedding model, a different chunking strategy, a corrected parser, a new metadata field you need to filter on, or a change of index type or distance metric. What these have in common is that the output is not comparable with the existing rows, so there is no incremental path. You cannot mix vectors from two embedding models in one index and expect distances to mean anything, and a chunking change invalidates every identifier you had.
That makes it a migration between two populations, and the shape is the familiar one: build the replacement beside the original, keep both correct while the source keeps moving, prove the replacement, switch atomically, retain the ability to switch back. The RAG-specific difficulty is that the build is slow — embedding ten million chunks is a bounded but multi-hour cost — and the corpus does not politely stop changing while you do it.
The alias is the whole cutover mechanism
If any application code, retriever config or notebook contains a literal index name, you have no atomic cutover; you have a deploy, and a deploy has a window in which some replicas read the old index and some the new. Put a single layer of indirection in front — a search alias where the store supports one, or otherwise a resolved name in configuration that every reader reads on each request rather than at startup — and cutover becomes one write that every subsequent query observes.
Two things follow that candidates usually miss. First, "atomic" only covers new queries. A multi-turn conversation whose earlier turns retrieved from the old index now has old and new evidence in one context window, and any cached retrieval results are still from the old population. If chunk boundaries changed, citations rendered in earlier turns may point at identifiers that no longer resolve. You either accept that seam or you pin a conversation to the index generation it started on, which is a real design choice with a real cost in how long you must keep the old index alive. Second, the alias has to be the only path, including for the tooling your team uses to debug, or you will spend an afternoon confused by a colleague reading the retired index directly.
Keeping the shadow index from falling behind
Snapshot the source, record the change-feed position at the instant of the snapshot, then backfill from the snapshot. Everything that changes after that watermark has to reach the new index as well as the old one. Either dual-write from the ingestion pipeline into both indexes for the duration, or let the backfill finish and then replay the change feed forward from the recorded watermark until the lag reaches zero. Dual writing is simpler to reason about and doubles write cost; replay is cheaper and requires that your change feed retains enough history to cover the whole build, which is exactly the assumption that fails on the third day of a slow backfill.
Deletions during the build are the sharp edge. A document deleted after the snapshot but before the backfill reaches it will be embedded from snapshot data and inserted into the new index, and the delete event may have been applied only to the old one. Handle it by making the tombstone authoritative in a manifest that both indexes consult, and by applying the accumulated tombstone set to the new index once more immediately before cutover. A rebuild that silently resurrects deleted documents is the single most common way a zero-downtime reindex turns into an incident report.
Verification is not a document count
Counts are a necessary gate and a weak one. They tell you the pipeline did not drop a shard; they tell you nothing about whether retrieval got worse. Stage the gates so cheap checks fail fast and expensive ones only run on a plausible index.
| Gate | What it catches |
|---|---|
| Manifest reconciliation, per source and per document | Whole batches silently skipped, tombstones not applied |
| Chunk-level spot checks against re-parsed source | Parser or chunker regressions, truncation, encoding damage |
| Gold-set retrieval metrics, old versus new | Aggregate recall or ranking regression |
| Shadowed production queries, result-set diff | Regressions your gold set does not represent |
| Latency and recall at the intended index parameters | A build that is only accurate because it is searching exhaustively |
The last of those catches a genuinely nasty case. A freshly built graph index queried with generous search parameters may look excellent and be far too slow at production settings, so measure quality at the parameters you intend to ship, not at whatever the defaults were during the build.
Diffing shadowed traffic deserves more than a mean. Run a sample of real queries against both indexes and look at the distribution of overlap in the top results and at rank displacement, then read the tail by hand. The average will be reassuring while a specific query class — exact identifiers, short queries, one language, one document type — has collapsed. That tail is what your users will report on the first day.
What a new model changes beyond the vectors
If the embedding model changed, the numbers around it changed too. Score distributions are model-specific, so any absolute similarity threshold you used to decide "no relevant results, refuse to answer" is now calibrated for the wrong model and must be re-derived. So are the weights in any hybrid fusion, and any reranker cut-off tuned against the old candidate set. Dimensionality changes affect index memory and possibly the store's supported configuration. State this unprompted: the honest answer is that the new index is a new retrieval system, and the tuning that surrounded the old one does not transfer just because the code did.
Cutover, and the rollback you have to still be paying for
Cut over behind whatever slice granularity your query layer supports — one tenant, one cohort, a percentage of traffic — because a percentage rollout that keeps a given user consistently on one generation is far more interpretable than one that flips them per request. Watch the retrieval metrics you can see live: proportion of queries returning no results above threshold, reranker score distribution, answer refusal rate, and citation-click behaviour if you have it.
Then the part that gets cut for schedule reasons and should not be. Keep writing to the old index after cutover for a defined retention window, because an alias switch is only a rollback if the thing you would switch back to is still current. The window is a business decision, not a technical one: long enough to have seen a full traffic cycle and whatever weekly job exercises the corpus differently. Only after that do you stop dual writing, and only then do you delete, because until you delete you are paying for two copies of a graph index in memory and that cost is usually what forces the timeline in the first place.
Likely follow-ups
- The new model has different dimensionality and a different score distribution. What breaks besides the index?
- Halfway through the backfill you find a parsing bug in the new pipeline. Restart or repair in place?
- How would you cut over one tenant at a time, and what does that require of the query layer?
- Your gold set says the new index is better and shadowed traffic says it is worse. How do you resolve that?
Related questions
- A better embedding model has come out. What does moving to it cost you?hardAlso on embeddings and reindexing5 min
- You need to migrate the schema of a 400-million-row table on a live system. Talk me through the plan, the backup you would want first, and how the connection pool affects it.hardAlso on zero-downtime6 min
- Your RAG system cannot answer a question whose answer is definitely in the documents. Where is the fault?hardAlso on embeddings4 min
- How do you isolate tenants in a shared vector index?hardAlso on embeddings5 min
- How do you replace a system that cannot be switched off?hardAlso on dual-write6 min
- What does a text embedding encode, and what does it fail to encode?mediumAlso on embeddings4 min
- A user's access to a document set is revoked. What has to happen across your RAG stack?hardSame kind of round: scenario6 min
- How would you autoscale a GPU inference service?hardSame kind of round: design5 min