Reindexing
Changing a mapping or shard count without downtime, using reindex, aliases and dual writes.
Reindexing is how you change anything that cannot be changed in place: a field's type, an analyzer, the primary shard count, or the index's structure.
The alias pattern
// 1. Create the new index with the corrected mapping.
PUT /articles-v2
{ "settings": { "number_of_shards": 6, "refresh_interval": "-1", "number_of_replicas": 0 },
"mappings": { "properties": { "title": { "type": "text", "analyzer": "english" } } } }
// 2. Copy the data.
POST /_reindex?wait_for_completion=false
{
"source": { "index": "articles-v1", "size": 2000 },
"dest": { "index": "articles-v2" }
}
// 3. Restore normal settings once the copy is done.
PUT /articles-v2/_settings
{ "index": { "refresh_interval": "1s", "number_of_replicas": 1 } }
// 4. Swap the alias atomically.
POST /_aliases
{ "actions": [
{ "remove": { "index": "articles-v1", "alias": "articles" } },
{ "add": { "index": "articles-v2", "alias": "articles" } }
]}Disabling refresh and replicas during the copy makes it substantially faster; restoring them afterwards is a step that is easy to forget and expensive to miss.
Monitoring and controlling the task
GET /_tasks?actions=*reindex&detailed
POST /_tasks/<task-id>/_cancel// Throttle to limit impact on production traffic.
POST /_reindex?requests_per_second=1000requests_per_second can also be changed on a running task with the rethrottle API.
Keeping the new index current
_reindex copies a snapshot of the source as it was; documents written afterwards are not included.
Two ways to close that gap:
Dual write. The application writes to both indices during the migration, then reads switch over. Most control, most application work.
Catch-up reindex. After the bulk copy, reindex documents modified since it started, using a timestamp field:
POST /_reindex
{
"source": {
"index": "articles-v1",
"query": { "range": { "updated_at": { "gte": "2026-07-31T02:00:00Z" } } }
},
"dest": { "index": "articles-v2", "op_type": "index" }
}This requires every document to carry a reliable updated_at, which is worth having anyway.
Remote reindex
POST /_reindex
{
"source": {
"remote": { "host": "https://old-cluster:9200", "username": "…", "password": "…" },
"index": "articles"
},
"dest": { "index": "articles" }
}Requires the remote host to be allowlisted in reindex.remote.whitelist. This is the usual path for
a cluster-to-cluster migration or a major-version upgrade.
Verification before the swap
Compare document counts, spot-check documents by id, and run the application's most important queries against both indices, comparing result sets and ordering. Relevance can change when an analyzer changes — that is often the point, and it should still be observed deliberately rather than discovered by users.