Index Architecture
Shards, replicas, segments and the routing that decides which node answers a query.
Shards and Replicas
An index is divided into primary shards at creation. Each primary can have replica shards, which are full copies serving reads and providing redundancy.
PUT /orders
{
"settings": {
"number_of_shards": 3,
"number_of_replicas": 1,
"refresh_interval": "30s"
}
}A document is routed to a shard by hash(_routing) % number_of_primary_shards, where _routing
defaults to the document id. That formula is why the primary count is immutable: changing it would
route existing documents to different shards.
How queries execute
- A coordinating node receives the request.
- It fans out to one copy of each shard — primary or replica.
- Each shard executes locally and returns its top results.
- The coordinator merges, ranks and, in the query-then-fetch model, retrieves the documents.
Query latency is therefore bounded by the slowest shard, not the average. More shards means more parallelism and a longer tail. See the tail latency discussion in Shared-Nothing Architecture.
Custom routing
If queries always filter by one field, routing documents by it means a query touches one shard instead of all of them:
POST /orders/_doc?routing=tenant-42
{ "tenant_id": "tenant-42", "total_cents": 19900 }
GET /orders/_search?routing=tenant-42
{ "query": { "term": { "tenant_id": "tenant-42" } } }The trade is skew: a large tenant concentrates on one shard. This is the same bargain as sharding elsewhere.
Segments
Each shard is a set of immutable Lucene segments. New documents create new segments; deletes mark documents in place. Background merges combine segments and physically remove deleted documents.
GET /_cat/segments/orders?v
GET /orders/_stats/segmentsIndex aliases
An alias is a pointer to one or more indices. Aliases are what make reindexing and rollover transparent to applications:
POST /_aliases
{
"actions": [
{ "remove": { "index": "orders-v1", "alias": "orders" } },
{ "add": { "index": "orders-v2", "alias": "orders" } }
]
}The swap is atomic. Applications should always read and write through an alias, never a concrete index name — that single habit is what makes every later structural change possible without downtime.