Type to search.

Reindex a time series data stream

Serverless Elasticsearch

Elastic Cloud Serverless projects are autoscaled environments, fully managed by Elastic and available on Elastic Cloud.

Availability

  • Generally available

    This functionality is generally available and ready for production usage.

Serverless Observability

Elastic Cloud Serverless projects are autoscaled environments, fully managed by Elastic and available on Elastic Cloud.

Availability

  • Generally available

    This functionality is generally available and ready for production usage.

Serverless Security

Elastic Cloud Serverless projects are autoscaled environments, fully managed by Elastic and available on Elastic Cloud.

Availability

  • Generally available

    This functionality is generally available and ready for production usage.

Serverless Vector Database Unavailable

Elastic Cloud Serverless projects are autoscaled environments, fully managed by Elastic and available on Elastic Cloud.

Availability

  • Unavailable

    This functionality is not available in Serverless Elasticsearch Vector Database projects.

Stack

The Elastic Stack includes Elastic's core products such as Elasticsearch, Kibana, Logstash, and Beats.

Availability

  • Generally available

    This functionality is generally available and ready for production usage.

Unless stated otherwise on the page, this functionality is available when your Elastic Stack is deployed on Elastic Cloud Hosted, Elastic Cloud Enterprise, Elastic Cloud on Kubernetes, and self-managed environments.

This documentation corresponds to the latest patch available for each minor version. If you're not using the latest patch, check the release notes for changes.

Copy documents from an existing time series data stream (TSDS) into a new data stream when you need to change mappings or static index settings, or when you want to filter or transform documents during the copy. A TSDS needs extra steps because it stores metrics in time-bound backing indices and Elasticsearch accepts a document only when its @timestamp falls in one of those time ranges.

Use this process for a TSDS that doesn't have a downsampling configuration. To reindex a downsampled data stream, reindex the backing indices individually, then add them to a new, empty data stream.

For a major version upgrade, use the reindex legacy backing indices API instead of this reindex operation.

  • You must be familiar with TSDS concepts. Try the quickstart for a hands-on introduction.
  • You must have the following permissions:
    • Cluster privileges
      • manage_index_templates to create a template
      • The Elastic Stack includes Elastic's core products such as Elasticsearch, Kibana, Logstash, and Beats. Availability Generally available from 9.0 to 9.4 This functionality is generally available and ready for production usage. Unless stated otherwise on the page, this functionality is available when your Elastic Stack is deployed on Elastic Cloud Hosted, Elastic Cloud Enterprise, Elastic Cloud on Kubernetes, and self-managed environments. This documentation corresponds to the latest patch available for each minor version. If you're not using the latest patch, check the release notes for changes. manage_ilm if you use index lifecycle management
      • The Elastic Stack includes Elastic's core products such as Elasticsearch, Kibana, Logstash, and Beats. Availability Generally available since 9.5 This functionality is generally available and ready for production usage. Unless stated otherwise on the page, this functionality is available when your Elastic Stack is deployed on Elastic Cloud Hosted, Elastic Cloud Enterprise, Elastic Cloud on Kubernetes, and self-managed environments. This documentation corresponds to the latest patch available for each minor version. If you're not using the latest patch, check the release notes for changes. manage to update cluster settings
    • Index privileges
      • create_doc and create_index to create a TSDS
      • read on the source and write on the destination to reindex a TSDS
      • manage to roll over a TSDS
      • manage_data_stream_lifecycle if you use data stream lifecycle
      • The Elastic Stack includes Elastic's core products such as Elasticsearch, Kibana, Logstash, and Beats. Availability Generally available since 9.5 This functionality is generally available and ready for production usage. Unless stated otherwise on the page, this functionality is available when your Elastic Stack is deployed on Elastic Cloud Hosted, Elastic Cloud Enterprise, Elastic Cloud on Kubernetes, and self-managed environments. This documentation corresponds to the latest patch available for each minor version. If you're not using the latest patch, check the release notes for changes. auto_configure to automatically create past indices

The examples on this page use Dev Tools Console syntax. You must have access to Dev Tools Console in Kibana or another way to make Elasticsearch API requests.

  1. Turn on past index creation

    Elasticsearch can create missing backing indices when you add data that precedes existing time ranges. To enable this feature, update the cluster settings:

    JSON
    PUT _cluster/settings
    {
      "persistent": {
        "data_stream.past_tsdb_index_creation_enabled": true,
        "data_streams.past_tsdb_index_interval": "2d"
      }
    }
    1. These settings are persistent and apply to all data streams in the cluster.
    2. By default, each past backing index covers one day of data. Refer to data_streams.past_tsdb_index_interval.

    If you do not want to use this feature, you can use the steps provided for earlier versions, which include calculating time bounds and applying temporary index template settings.

  2. Create the destination index template

    Create an index template for the destination TSDS with the create an index template API. Use your preferred mappings and settings. For example:

    JSON
    PUT _index_template/my-new-tsds-template
    {
      "index_patterns": ["my-new-tsds"],
      "priority": 100,
      "data_stream": {},
      "template": {
        "settings": {
          "index.mode": "time_series"
        },
        "mappings": {
          "properties": {
            "@timestamp": {
              "type": "date"
            },
            "dimension_field": {
              "type": "keyword",
              "time_series_dimension": true
            },
            "metric_field": {
              "type": "double",
              "time_series_metric": "gauge"
            }
          }
        }
      }
    }

    Don't add data stream lifecycle or index lifecycle management details to the template yet. That keeps lifecycle actions such as downsampling from modifying the destination while you reindex.

  3. Create the destination data stream

    Create a data stream with the create a data stream API. The data stream name must match the index_patterns in your index template. For example:

    JSON
    PUT _data_stream/my-new-tsds
  4. Run the reindex operation

    Use the reindex API to copy documents from the source to the destination data stream. For example:

    JSON
    POST /_reindex
    {
      "source": {
        "index": "my-old-tsds"
      },
      "dest": {
        "index": "my-new-tsds",
        "op_type": "create"
      }
    }

    Elasticsearch adds past backing indices to the destination data stream because you turned on past index creation.

    Use the get data stream API to check that backing indices cover the timestamps you reindexed. For example:

    JSON
    GET _data_stream/my-new-tsds

    The response lists each backing index and the time range it accepts.

  5. Add data stream lifecycle

    Optionally add a data stream lifecycle to manage retention, performance, and storage. For example, use the update data stream lifecycles API:

    JSON
    PUT _data_stream/my-new-tsds/_lifecycle
    {
      "enabled": true,
      "data_retention": "365d"
    }
    1. The retention period of this data stream is set to 365 days. This means that Elasticsearch is allowed to delete data that is older than a year at its own discretion.

    For more details, refer to Set a data stream's lifecycle.

    Alternatively, you can use index lifecycle management. Refer to Create an index lifecycle management policy in Elasticsearch and Apply an index lifecycle policy to an existing Elasticsearch index.

  6. Turn off past index creation

    If you don't want the past index creation feature enabled for all of the data streams in your cluster, turn it off:

    JSON
    PUT _cluster/settings
    {
      "persistent": {
        "data_stream.past_tsdb_index_creation_enabled": false
      }
    }

    Refer to data_streams.past_tsdb_index_interval.

  1. Identify time bounds

    Search for the lowest and highest @timestamp values in the old data stream. For example:

    JSON
    POST my-old-tsds/_search?size=0
    {
      "aggs": {
        "min_ts": { "min": { "field": "@timestamp" } },
        "max_ts": { "max": { "field": "@timestamp" } }
      }
    }

    Add a buffer on both sides of these values. Subtract a small amount from the min date and add a small amount to the max date. For example, if your observed range is from 2026-10-13T17:50:23.747Z to 2026-10-13T18:50:21.747Z, use values like 2026-10-13T17:50:22.747Z and 2026-10-13T18:50:22.747Z when you create the destination index template.

  2. Identify number of shards

    Calculate the sum of all primary shards of all backing indices of the old data stream. For example, list the backing indices for the data stream with the get data streams API:

    JSON
    GET _data_stream/my-old-tsds

    For each backing index, check its index.number_of_shards setting. For example:

    JSON
    GET .ds-my-old-tsds-*/_settings/index.number_of_shards

    Sum theindex.number_of_shards values for all backing indices of the source data stream. This value is used when you create the destination index template.

  3. Create the destination index template

    Create an index template for the destination TSDS with the create an index template API. Use temporary settings so the first backing index can accept the source timestamps:

    1. Set index.time_series.start_time and index.time_series.end_time to the time bounds you identified in the previous step.
    2. Set index.number_of_shards to the number of shards you identified in the previous step.
    3. Clear the index.lifecycle.name index setting (if any), to prevent index lifecycle management from modifying the destination data stream during reindexing.
    4. (Optional) Set index.number_of_replicas to zero to speed up reindexing. Because the data is copied, you don't need replicas.
    JSON
    PUT _index_template/my-new-tsds-template
    {
      "index_patterns": ["my-new-tsds"],
      "priority": 100,
      "data_stream": {},
      "template": {
        "settings": {
          "index.mode": "time_series",
          "index.time_series.start_time": "2023-01-01T00:00:00Z",
          "index.time_series.end_time": "2025-01-01T00:00:00Z",
          "index.number_of_shards": 6,
          "index.number_of_replicas": 0,
          "index.lifecycle.name": null
        },
        "mappings": {
          "properties": {
            "@timestamp": {
              "type": "date"
            },
            "dimension_field": {
              "type": "keyword",
              "time_series_dimension": true
            },
            "metric_field": {
              "type": "double",
              "time_series_metric": "gauge"
            }
          }
        }
      }
    }
    1. Lowest timestamp value in the old data stream minus a small buffer
    2. Highest timestamp value in the old data stream plus a small buffer
    3. Sum of the primary shards from all source backing indices
    4. Speed up reindexing
    5. Pause index lifecycle management if it was configured
  4. Create the destination data stream

    Create a data stream with the create a data stream API. The data stream name must match the index_patterns in your index template. For example:

    JSON
    PUT _data_stream/my-new-tsds
  5. Run the reindex operation

    Use the reindex API to copy documents from the source to the destination data stream. For example:

    JSON
    POST /_reindex
    {
      "source": {
        "index": "my-old-tsds"
      },
      "dest": {
        "index": "my-new-tsds",
        "op_type": "create"
      }
    }

    Use the get data stream API to check that backing indices cover the timestamps you reindexed. For example:

    JSON
    GET _data_stream/my-new-tsds

    The response lists each backing index and the time range it accepts.

  6. Restore the destination index template

    After reindexing completes, update the index template to remove the temporary settings:

    • Remove the overrides for index.time_series.start_time and index.time_series.end_time.
    • Restore the values of index.number_of_shards, index.number_of_replicas, and index.lifecycle.name (as applicable).
    JSON
    PUT _index_template/my-new-tsds-template
    {
      "index_patterns": ["my-new-tsds"],
      "priority": 100,
      "data_stream": {},
      "template": {
        "settings": {
          "index.mode": "time_series",
          "index.number_of_replicas": 1,
          "index.lifecycle.name": "my-ilm-policy"
        },
        "mappings": {
          "properties": {
            "@timestamp": {
              "type": "date"
            },
            "dimension_field": {
              "type": "keyword",
              "time_series_dimension": true
            },
            "metric_field": {
              "type": "double",
              "time_series_metric": "gauge"
            }
          }
        }
      }
    }
    1. Restore replicas
    2. Re-enable index lifecycle management if it was configured
  7. Add data stream lifecycle

    Optionally add a data stream lifecycle to manage retention, performance, and storage. For example, use the update data stream lifecycles API:

    JSON
    PUT _data_stream/my-new-tsds/_lifecycle
    {
      "enabled": true,
      "data_retention": "365d"
    }
    1. The retention period of this data stream is set to 365 days. This means that Elasticsearch is allowed to delete data that is older than a year at its own discretion.

    For more details, refer to Set a data stream's lifecycle.

    Alternatively, you can use index lifecycle management. Refer to Create an index lifecycle management policy in Elasticsearch and Apply an index lifecycle policy to an existing Elasticsearch index.

  8. Roll over for new data

    The reindex operation copies documents into a single backing index of the destination data stream. Roll over the data stream so new documents go to a fresh backing index created with the intended lifecycle configuration. For example, use the roll over API:

    JSON
    POST my-new-tsds/_rollover/

    When this step is complete, the destination data stream can accept new documents.

  1. Identify time bounds

    Search for the lowest and highest @timestamp values in the old data stream. For example:

    JSON
    POST my-old-tsds/_search?size=0
    {
      "aggs": {
        "min_ts": { "min": { "field": "@timestamp" } },
        "max_ts": { "max": { "field": "@timestamp" } }
      }
    }

    Add a buffer on both sides of these values. Subtract a small amount from the min date and add a small amount to the max date. For example, if your observed range is from 2026-10-13T17:50:23.747Z to 2026-10-13T18:50:21.747Z, use values like 2026-10-13T17:50:22.747Z and 2026-10-13T18:50:22.747Z in the next step.

  2. Create the destination index template

    Create an index template for the destination TSDS with the create an index template API. Set index.time_series.start_time and index.time_series.end_time to the time bounds identified in the preceding step so the first backing index can accept the source timestamps. For example:

    JSON
    PUT _index_template/my-new-tsds-template
    {
      "index_patterns": ["my-new-tsds"],
      "priority": 100,
      "data_stream": {},
      "template": {
        "settings": {
          "index.mode": "time_series",
          "index.time_series.start_time": "2023-01-01T00:00:00Z",
          "index.time_series.end_time": "2025-01-01T00:00:00Z",
        },
        "mappings": {
          "properties": {
            "@timestamp": {
              "type": "date"
            },
            "dimension_field": {
              "type": "keyword",
              "time_series_dimension": true
            },
            "metric_field": {
              "type": "double",
              "time_series_metric": "gauge"
            }
          }
        }
      }
    }
    1. Lowest timestamp value in the old data stream
    2. Highest timestamp value in the old data stream

    Don't add optional data stream lifecycle details such as downsampling or data retention to the template yet. By using only the default configuration, you reduce the actions that can modify the destination while you reindex.

  3. Create the destination data stream

    Create a data stream with the create a data stream API. The data stream name must match the index_patterns in your index template. For example:

    JSON
    PUT _data_stream/my-new-tsds
  4. Run the reindex operation

    Use the reindex API to copy documents from the source to the destination data stream. For example:

    JSON
    POST /_reindex
    {
      "source": {
        "index": "my-old-tsds"
      },
      "dest": {
        "index": "my-new-tsds",
        "op_type": "create"
      }
    }

    Documents land in that one backing index because its time range was set on the template.

    Use the get data stream API to check that the backing index covers the timestamps you reindexed. For example:

    JSON
    GET _data_stream/my-new-tsds

    The response lists each backing index and the time range it accepts.

  5. Restore the destination index template

    After reindexing completes, update the index template and remove index.time_series.start_time and index.time_series.end_time.

    JSON
    PUT _index_template/my-new-tsds-template
    {
      "index_patterns": ["my-new-tsds"],
      "priority": 100,
      "data_stream": {},
      "template": {
        "settings": {
          "index.mode": "time_series"
        },
        "mappings": {
          "properties": {
            "@timestamp": {
              "type": "date"
            },
            "dimension_field": {
              "type": "keyword",
              "time_series_dimension": true
            },
            "metric_field": {
              "type": "double",
              "time_series_metric": "gauge"
            }
          }
        }
      }
    }
  6. Add data stream lifecycle

    After the reindex completes, optionally customize the data stream lifecycle to manage retention, performance, and storage. For example, use the update data stream lifecycles API:

    JSON
    PUT _data_stream/my-new-tsds/_lifecycle
    {
      "enabled": true,
      "data_retention": "365d"
    }
    1. The retention period of this data stream is set to 365 days. This means that Elasticsearch is allowed to delete data that is older than a year at its own discretion.

    For more details, refer to Set a data stream's lifecycle.

  7. Roll over for new data

    The reindex operation copies documents into a single backing index of the destination data stream. Roll over the data stream so new documents go to a fresh backing index created with the intended lifecycle configuration. For example, use the roll over API:

    JSON
    POST my-new-tsds/_rollover/

    When this step is complete, the destination data stream can accept new documents. Later rollovers happen automatically.