AAI Agentic Handbook
Production & Ops

Index alias

Senior levelReviewed Oct 2026In 2 interview questions

A stable name (e.g. products-read) that points to a physical index, so you can rebuild a new index and repoint readers atomically with no client change.

In plain English

An index alias is a nickname for a search or vector index. Your application always queries catalog-read; behind the scenes that name points at catalog-v7. When you rebuild the index (new embedding model, new chunking), you build catalog-v8 next to it, check it, then move the nickname in one step. Nobody redeploys, and rolling back is moving the nickname back. It is the mechanism behind Blue-green deployment for search.

Analogy

A company's support phone number: the number on the website never changes, but the switchboard can route it to a new call centre overnight.

Common pitfall

Querying the physical index name directly from one service 'just for now'. The swap moves every reader except that one, which keeps serving the old embeddings against new query vectors, or breaks when the old index is deleted.

How it actually works

Elasticsearch and OpenSearch support atomic multi-action _aliases requests (remove old, add new in one call), and an alias can have one is_write_index. Qdrant has collection aliases with atomic change_aliases operations; Milvus has alter_alias. Where the store lacks aliases (pgvector tables, some managed vector DBs), emulate one with a config row or flag that the query service reads, or a Postgres view swapped in a transaction. Keep separate read and write aliases: during a migration writes go to both physical indexes (via the consumer, see Dual-write) while reads move only when the new index is verified. Version physical names with the embedding model and chunker (catalog_e5l-1024_c512_v8) so nothing ever queries a mismatched model. Clients must not cache the resolved name; they always call the alias. Delete old physical indexes on a schedule, because forgotten v3–v6 indexes double storage bills.

What I'd ship on day one

Read alias + write alias per logical index; physical names encode embedding model, dimension, chunker and version; swaps via Elasticsearch/OpenSearch _aliases or Qdrant change_aliases; config-row emulation for pgvector; old index retained 7 days then deleted by a scheduled job.

Worked example

An e-commerce catalog of 9M products moves from a 768-d to a 1024-d embedding. The team builds catalog_v8 (backfill 7 h), points the CDC consumer at both v7 and v8, runs shadow queries for 3 days (NDCG@10 0.71 → 0.76 on 2,000 judged queries), then swaps catalog-read with one _aliases call: remove catalog_v7, add catalog_v8. A filter bug on size facets appears an hour later; rollback is the reverse call, 400 ms. Fixed, re-swapped next day, v7 deleted after 7 days.

In the interview

Any index I expect to rebuild sits behind read and write aliases from day one, with model and chunker versions in the physical name. Rebuilds become build, dual-write, shadow, swap, keep the old one a week. The follow-up: 'your vector DB has no aliases?' I'd hold the active index name in a config table the query service reads per request, which gives the same atomic swap.

01Readersquery catalog-read
02Aliascatalog-read → v7
03Build v8backfill + dual-write
04Atomic swapremove v7, add v8
05Keep v7 7 daysrollback = swap back
The application never learns the physical index name; the alias is the contract.

Numbers worth knowing

Alias swap time
<1 ssingle atomic cluster-state update in Elasticsearch/OpenSearch
Storage during migration
~2×both physical indexes live with dual-writes
Rollback window
7 daysenough for quality feedback to surface on search changes

How to decide

WhenDo this
Rebuilding with a new embedding model or chunkerNew physical index, alias swap; never in-place.
Store supports native aliasesUse them with atomic multi-action swaps.
Store lacks aliases (pgvector table)Config row or view swapped in one transaction.
Per-tenant indexesOne alias per tenant so you can migrate tenants one at a time.

Cost maths

Overlap storage: 9M × 1024 dims × 4 bytes = 37 GB raw float32 per index, plus HNSW overhead ~1.5× ≈ 55 GB; two copies for a week on managed storage at ~$0.10–0.25/GB-month is a few dollars. The bigger cost is forgetting: five stale versions of a 55 GB index on SSD-backed nodes can mean an extra data node (~$500–1,000/month) for nothing.

Operating it

Time to scale up when…
  • More than 2 physical versions alive per logical index
  • Per-tenant indexes >1,000: automate alias management and migration waves
  • Swaps done by hand in the console: script them with pre-swap checks (doc count, golden-set recall)
What to monitor
  • Queries hitting physical (non-alias) index names: alert >0
  • Physical index versions per logical index: alert >2
  • Doc count and golden-set recall check before every swap: block if new < old by >0.5%

When it goes wrong

What users saw

Search relevance on an internal wiki dropped sharply for one department's app only, two weeks after a successful migration.

How it was caught

Relevance complaints, then traces showing that app querying wiki_v5 while all others used wiki-read → v6.

Root cause

That app had hardcoded the physical index name; it was now embedding queries with the new model and searching vectors from the old one.

Fix

Index-level permissions only allow reads through aliases; physical index names removed from app configs; a lint check for _v\d+ index names in code.

Sources

  1. Aliases — Elastic, 2025docs
  2. Collections (collection aliases) — Qdrant, 2025docs

Check yourself

Three questions. Every option is explained once you answer.

1ConceptWhy encode embedding model and chunker in physical index names?
2ScenarioYou use pgvector, which has no native alias, and need a zero-downtime index rebuild. What do you do?
3Calculation9M vectors × 1024 dims × 4 bytes, plus ~1.5× HNSW overhead. Roughly how big is one index?