Index rollover moves an Elasticsearch write alias from the current concrete index to the next generation before the old index becomes too large. It is useful for classic index families that still need alias-based writes instead of a data stream.

Alias-based rollover depends on one alias that receives writes. When that alias points to more than one index, exactly one target needs is_write_index set to true so Elasticsearch knows where new documents belong. A separate read alias can span old and new generations when searches should cover the whole index family.

Elastic recommends data streams for most append-only time-series data, while alias rollover still fits index families that need classic index names or last-write-wins updates. Use a name pattern that does not collide with built-in templates, send requests to the correct HTTP or HTTPS endpoint, and make sure repeated rollovers inherit the required mappings and settings from an index template or the rollover request body.

Steps to perform an index rollover in Elasticsearch:

  1. Create the initial index with a dedicated write alias, a separate read alias, and single-node replica settings.
    $ curl -sS --fail -H "Content-Type: application/json" -X PUT "http://localhost:9200/rollover-demo-000001?pretty&filter_path=acknowledged,shards_acknowledged,index" -d '{
      "settings": {
        "number_of_replicas": 0
      },
      "aliases": {
        "rollover-demo-write": {
          "is_write_index": true
        },
        "rollover-demo": {}
      }
    }'
    {
      "acknowledged" : true,
      "shards_acknowledged" : true,
      "index" : "rollover-demo-000001"
    }

    This example sets number_of_replicas to 0 so a one-node validation cluster stays GREEN. The zero-padded suffix lets Elasticsearch derive rollover-demo-000002 automatically, and the separate rollover-demo alias keeps older generations searchable after the write target moves.

  2. Index a test document through the write alias.
    $ curl -sS --fail -H "Content-Type: application/json" -X POST "http://localhost:9200/rollover-demo-write/_doc?refresh=wait_for&pretty&filter_path=_index,_id,result" -d '{
      "@timestamp": "2026-06-18T07:20:00Z",
      "message": "pre-rollover event"
    }'
    {
      "_index" : "rollover-demo-000001",
      "_id" : "aUgv2Z4BvVrvJFGtBmrf",
      "result" : "created"
    }

    Applications keep writing to rollover-demo-write while the backing index generation changes underneath it.

  3. Preview the rollover conditions without creating the next index yet.
    $ curl -sS --fail -H "Content-Type: application/json" -X POST "http://localhost:9200/rollover-demo-write/_rollover?dry_run=true&pretty" -d '{
      "conditions": {
        "max_docs": 1
      },
      "settings": {
        "number_of_replicas": 0
      },
      "aliases": {
        "rollover-demo": {}
      }
    }'
    {
      "acknowledged" : false,
      "shards_acknowledged" : false,
      "old_index" : "rollover-demo-000001",
      "new_index" : "rollover-demo-000002",
      "rolled_over" : false,
      "dry_run" : true,
      "lazy" : false,
      "conditions" : {
        "[max_docs: 1]" : true
      }
    }

    dry_run=true only evaluates the condition result, so acknowledged and rolled_over stay false. Including settings and aliases here previews the shape of the index that the real rollover should create.

  4. Run the rollover request against the write alias.
    $ curl -sS --fail -H "Content-Type: application/json" -X POST "http://localhost:9200/rollover-demo-write/_rollover?pretty" -d '{
      "conditions": {
        "max_docs": 1
      },
      "settings": {
        "number_of_replicas": 0
      },
      "aliases": {
        "rollover-demo": {}
      }
    }'
    {
      "acknowledged" : true,
      "shards_acknowledged" : true,
      "old_index" : "rollover-demo-000001",
      "new_index" : "rollover-demo-000002",
      "rolled_over" : true,
      "dry_run" : false,
      "lazy" : false,
      "conditions" : {
        "[max_docs: 1]" : true
      }
    }

    Rolling over only the write alias does not keep one-name searches across historical generations. Keep a separate read alias such as rollover-demo, or query an explicit pattern, when older indices must remain searchable after the write target advances.

  5. Inspect the write alias assignments after rollover.
    $ curl -sS --fail "http://localhost:9200/_cat/aliases/rollover-demo-write?v&s=index&h=alias,index,is_write_index"
    alias               index                is_write_index
    rollover-demo-write rollover-demo-000001 false
    rollover-demo-write rollover-demo-000002 true

    The write alias now marks rollover-demo-000002 as true and the previous generation as false. The _cat APIs are intended for human-readable inspection; use the JSON alias APIs for automation or programmatic checks.

  6. Index another test document through the write alias.
    $ curl -sS --fail -H "Content-Type: application/json" -X POST "http://localhost:9200/rollover-demo-write/_doc?refresh=wait_for&pretty&filter_path=_index,_id,result" -d '{
      "@timestamp": "2026-06-18T07:21:00Z",
      "message": "post-rollover event"
    }'
    {
      "_index" : "rollover-demo-000002",
      "_id" : "akgv2Z4BvVrvJFGtC2pV",
      "result" : "created"
    }

    The response _index field confirms that new writes land in the latest rollover generation.

  7. Search through the read alias to confirm both generations remain queryable.
    $ curl -sS --fail "http://localhost:9200/rollover-demo/_search?pretty&size=10&sort=%40timestamp:asc&filter_path=hits.total,hits.hits._index,hits.hits._source.message"
    {
      "hits" : {
        "total" : {
          "value" : 2,
          "relation" : "eq"
        },
        "hits" : [
          {
            "_index" : "rollover-demo-000001",
            "_source" : {
              "message" : "pre-rollover event"
            }
          },
          {
            "_index" : "rollover-demo-000002",
            "_source" : {
              "message" : "post-rollover event"
            }
          }
        ]
      }
    }

    Reading through rollover-demo returns both generations, which is why separate read and write aliases are useful for alias-based rollover.

  8. Delete the demo indices if they were created only for validation.
    $ curl -sS --fail -X DELETE "http://localhost:9200/rollover-demo-000001,rollover-demo-000002?pretty"
    {
      "acknowledged" : true
    }

    Deleting rollover generations permanently removes their documents. Skip this cleanup on production index families unless the indices are disposable or a retention plan has already approved the deletion.