Reindexing or upgrading Elasticsearch can be risky when your system is already in production.
If you change mappings, update analyzers, or move to a new version, stopping the cluster is not an option.
That’s where the blue-green strategy helps, it allows you to build a new index (or cluster), test it, and switch traffic smoothly without downtime.
What Is Blue-Green Deployment?
In a blue-green setup, you have two environments:
Environment | Purpose |
---|---|
Blue | The current (live) index or cluster that handles all user queries |
Green | The new index or cluster that receives fresh data and testing |
Once the green environment is ready and validated, you simply switch an alias or connection, users instantly move from blue to green. If something goes wrong, you can roll back to blue within seconds.
When Do You Need It?
Blue-green deployment is useful when you must:
- Change mappings or analyzers (e.g., modify a field type from
text
tokeyword
) - Add new fields that require reindexing
- Upgrade Elasticsearch to a new major version (for example, from 7.x → 8.x)
- Clean up corrupted data or fix index settings
- Move to new hardware or cloud nodes
Blue-Green Reindex Strategy (Same Cluster)
This is the simplest case — both blue and green indices exist inside the same cluster.
Step 1 Create the New Index (Green)
Design your new mapping carefully.
PUT my_index_v2 { "settings": { "number_of_shards": 5, "number_of_replicas": 1 }, "mappings": { "properties": { "title": { "type": "text", "analyzer": "english" }, "price": { "type": "float" } } } }
Step 2 Reindex Data from the Old Index
Copy all documents from the blue index to the new one.
POST _reindex { "source": { "index": "my_index_v1" }, "dest": { "index": "my_index_v2" }, "conflicts": "proceed" }
For large datasets, run it in the background:
POST _reindex?wait_for_completion=false
and track progress:
GET _tasks?detailed=true&actions=*reindex
Step 3 Test the New Index
Compare document counts:
GET my_index_v1/_count GET my_index_v2/_count
Try a few search queries and aggregations to confirm the same results.
You can also benchmark query latency or relevance scoring.
Step 4 Switch Aliases
Use aliases to change which index your application points to.
POST /_aliases { "actions": [ { "remove": { "index": "my_index_v1", "alias": "my_index" } }, { "add": { "index": "my_index_v2", "alias": "my_index" } } ] }
All apps that query my_index
will now automatically read from the new index — zero downtime.
Step 5 Clean Up or Archive
When you are sure the new version works:
DELETE my_index_v1
Or snapshot it for backup before deletion.
Handling Continuous Writes
If your system is still receiving new data while reindexing, you have two options:
Option A Dual Write
Write to both indices (v1
and v2
) until the switch is done.
After switching, stop writing to v1
.
Option B Catch-Up Reindex
Pause writes for a short time (maintenance window), reindex only the delta:
POST _reindex { "source": { "index": "my_index_v1", "query": { "range": { "@timestamp": { "gte": "2025-10-05T00:00:00Z" } } } }, "dest": { "index": "my_index_v2" } }
Then switch aliases.