﻿---
title: Reindex a time series data stream
description: Reindex documents into a new time series data stream with the reindex API. Account for time-bound backing indices and timestamp windows.
url: https://docs-v3-preview.elastic.dev/elastic/docs-content/pull/8715/manage-data/data-store/data-streams/reindex-tsds
products:
  - Elastic Documentation
  - Elasticsearch
applies_to:
  - Serverless Elasticsearch projects: Generally available
  - Serverless Observability projects: Generally available
  - Serverless Security projects: Generally available
  - Serverless Elasticsearch Vector Database projects: Unavailable
  - Elastic Stack: Generally available
---

# Reindex a time series data stream
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](/elastic/docs-content/pull/8715/manage-data/data-store/data-streams/modify-data-stream#data-streams-use-reindex-to-change-mappings-settings), or when you want to [filter or transform documents](https://docs-v3-preview.elastic.dev/elastic/elasticsearch/tree/main/reference/elasticsearch/rest-apis/reindex-indices) 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](https://docs-v3-preview.elastic.dev/elastic/docs-content/pull/8715/manage-data/data-store/data-streams/downsampling-time-series-data-stream) 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](https://www.elastic.co/docs/api/doc/elasticsearch/operation/operation-indices-migrate-reindex) instead of this reindex operation.

## Before you begin

- You must be familiar with [TSDS concepts](https://docs-v3-preview.elastic.dev/elastic/docs-content/pull/8715/manage-data/data-store/data-streams/time-series-data-stream-tsds). Try the [quickstart](https://docs-v3-preview.elastic.dev/elastic/docs-content/pull/8715/manage-data/data-store/data-streams/quickstart-tsds) for a hands-on introduction.
- You must have the following permissions:
  - [Cluster privileges](https://docs-v3-preview.elastic.dev/elastic/elasticsearch/tree/main/reference/elasticsearch/security-privileges#privileges-list-cluster)
  - `manage_index_templates` to create a template
- <applies-to>Elastic Stack: Generally available from 9.0 to 9.4</applies-to> `manage_ilm` if you use [index lifecycle management](https://docs-v3-preview.elastic.dev/elastic/docs-content/pull/8715/manage-data/lifecycle/index-lifecycle-management)
- <applies-to>Elastic Stack: Generally available since 9.5</applies-to> `manage` to update cluster settings
- [Index privileges](https://docs-v3-preview.elastic.dev/elastic/elasticsearch/tree/main/reference/elasticsearch/security-privileges#privileges-list-indices)
  - `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](https://docs-v3-preview.elastic.dev/elastic/docs-content/pull/8715/manage-data/lifecycle/data-stream)
- <applies-to>Elastic Stack: Generally available since 9.5</applies-to> `auto_configure` to automatically create past indices

The examples on this page use Dev Tools [**Console**](https://docs-v3-preview.elastic.dev/elastic/docs-content/pull/8715/explore-analyze/query-filter/tools/console) syntax.
You must have access to [Dev Tools Console](https://docs-v3-preview.elastic.dev/elastic/docs-content/pull/8715/explore-analyze/query-filter/tools/console) in Kibana or another way to make Elasticsearch API requests.

## Reindex the data stream

<applies-switch>
  <applies-item title="stack: ga 9.5+" applies-to="Elastic Stack: Generally available since 9.5">
    <stepper>
      <step title="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

        {
          "persistent": { <1>
            "data_stream.past_tsdb_index_creation_enabled": true,
            "data_streams.past_tsdb_index_interval": "2d" <1>
          }
        }
        ```

        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`](https://docs-v3-preview.elastic.dev/elastic/elasticsearch/tree/main/reference/elasticsearch/configuration-reference/miscellaneous-cluster-settings#time-series-data-stream).
        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.
      </step>

      <step title="Create the destination index template">
        Create an index template for the destination TSDS with the [create an index template API](https://www.elastic.co/docs/api/doc/elasticsearch/operation/operation-indices-put-index-template).
        Use your preferred mappings and settings.
        For example:
        ```json

        {
          "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.
      </step>

      <step title="Create the destination data stream">
        Create a data stream with the [create a data stream API](https://www.elastic.co/docs/api/doc/elasticsearch/operation/operation-indices-create-data-stream).
        The data stream name must match the `index_patterns` in your index template.
        For example:
        ```json
        ```
      </step>

      <step title="Run the reindex operation">
        Use the [reindex API](https://www.elastic.co/docs/api/doc/elasticsearch/operation/operation-reindex) to copy documents from the source to the destination data stream.
        For example:
        ```json

        {
          "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](https://www.elastic.co/docs/api/doc/elasticsearch/operation/operation-indices-get-data-stream) to check that backing indices cover the timestamps you reindexed.
        For example:
        ```json
        ```
        The response lists each backing index and the time range it accepts.
      </step>

      <step title="Add data stream lifecycle">
        Optionally add a data stream lifecycle to manage retention, performance, and storage.
        For example, use the [update data stream lifecycles](https://www.elastic.co/docs/api/doc/elasticsearch/operation/operation-indices-put-data-lifecycle) API:
        ```json

        {
          "enabled": true,
          "data_retention": "365d" <1>
        }
        ```

        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](/elastic/docs-content/pull/8715/manage-data/lifecycle/data-stream/tutorial-update-existing-data-stream#set-lifecycle).
        Alternatively, you can use index lifecycle management. Refer to [Create an index lifecycle management policy in Elasticsearch](https://docs-v3-preview.elastic.dev/elastic/docs-content/pull/8715/manage-data/lifecycle/index-lifecycle-management/configure-lifecycle-policy) and [Apply an index lifecycle policy to an existing Elasticsearch index](https://docs-v3-preview.elastic.dev/elastic/docs-content/pull/8715/manage-data/lifecycle/index-lifecycle-management/policy-apply).
      </step>

      <step title="Turn off past index creation">
        If you don't want the [past index creation](/elastic/docs-content/pull/8715/manage-data/data-store/data-streams/time-bound-tsds#tsds-past-index-creation) feature enabled for all of the data streams in your cluster, turn it off:
        ```json

        {
          "persistent": {
            "data_stream.past_tsdb_index_creation_enabled": false
          }
        }
        ```
        Refer to [`data_streams.past_tsdb_index_interval`](https://docs-v3-preview.elastic.dev/elastic/elasticsearch/tree/main/reference/elasticsearch/configuration-reference/miscellaneous-cluster-settings#time-series-data-stream).
      </step>
    </stepper>
  </applies-item>

  <applies-item title="stack: ga 9.0-9.4" applies-to="Elastic Stack: Generally available from 9.0 to 9.4">
    <stepper>
      <step title="Identify time bounds">
        Search for the lowest and highest `@timestamp` values in the old data stream.
        For example:
        ```json

        {
          "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.
      </step>

      <step title="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](https://www.elastic.co/docs/api/doc/elasticsearch/operation/operation-indices-get-data-stream):
        ```json
        ```
        For each backing index, check its `index.number_of_shards` setting.
        For example:
        ```json
        ```
        Sum the`index.number_of_shards` values for all backing indices of the source data stream.
        This value is used when you create the destination index template.
      </step>

      <step title="Create the destination index template">
        Create an index template for the destination TSDS with the [create an index template API](https://www.elastic.co/docs/api/doc/elasticsearch/operation/operation-indices-put-index-template).
        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

        {
          "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", <1>
              "index.time_series.end_time": "2025-01-01T00:00:00Z", <2>
              "index.number_of_shards": 6, <3>
              "index.number_of_replicas": 0, <4>
              "index.lifecycle.name": null <5>
            },
            "mappings": {
              "properties": {
                "@timestamp": {
                  "type": "date"
                },
                "dimension_field": {
                  "type": "keyword",
                  "time_series_dimension": true
                },
                "metric_field": {
                  "type": "double",
                  "time_series_metric": "gauge"
                }
              }
            }
          }
        }
        ```
      </step>

      <step title="Create the destination data stream">
        Create a data stream with the [create a data stream API](https://www.elastic.co/docs/api/doc/elasticsearch/operation/operation-indices-create-data-stream).
        The data stream name must match the `index_patterns` in your index template.
        For example:
        ```json
        ```
      </step>

      <step title="Run the reindex operation">
        Use the [reindex API](https://www.elastic.co/docs/api/doc/elasticsearch/operation/operation-reindex) to copy documents from the source to the destination data stream.
        For example:
        ```json

        {
          "source": {
            "index": "my-old-tsds"
          },
          "dest": {
            "index": "my-new-tsds",
            "op_type": "create"
          }
        }
        ```
        Use the [get data stream API](https://www.elastic.co/docs/api/doc/elasticsearch/operation/operation-indices-get-data-stream) to check that backing indices cover the timestamps you reindexed.
        For example:
        ```json
        ```
        The response lists each backing index and the time range it accepts.
      </step>

      <step title="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

        {
          "index_patterns": ["my-new-tsds"],
          "priority": 100,
          "data_stream": {},
          "template": {
            "settings": {
              "index.mode": "time_series",
              "index.number_of_replicas": 1, <1>
              "index.lifecycle.name": "my-ilm-policy" <2>
            },
            "mappings": {
              "properties": {
                "@timestamp": {
                  "type": "date"
                },
                "dimension_field": {
                  "type": "keyword",
                  "time_series_dimension": true
                },
                "metric_field": {
                  "type": "double",
                  "time_series_metric": "gauge"
                }
              }
            }
          }
        }
        ```
      </step>

      <step title="Add data stream lifecycle">
        Optionally add a data stream lifecycle to manage retention, performance, and storage.
        For example, use the [update data stream lifecycles](https://www.elastic.co/docs/api/doc/elasticsearch/operation/operation-indices-put-data-lifecycle) API:
        ```json

        {
          "enabled": true,
          "data_retention": "365d" <1>
        }
        ```

        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](/elastic/docs-content/pull/8715/manage-data/lifecycle/data-stream/tutorial-update-existing-data-stream#set-lifecycle).
        Alternatively, you can use index lifecycle management. Refer to [Create an index lifecycle management policy in Elasticsearch](https://docs-v3-preview.elastic.dev/elastic/docs-content/pull/8715/manage-data/lifecycle/index-lifecycle-management/configure-lifecycle-policy) and [Apply an index lifecycle policy to an existing Elasticsearch index](https://docs-v3-preview.elastic.dev/elastic/docs-content/pull/8715/manage-data/lifecycle/index-lifecycle-management/policy-apply).
      </step>

      <step title="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](https://www.elastic.co/docs/api/doc/elasticsearch/operation/operation-indices-rollover):
        ```json
        ```
        When this step is complete, the destination data stream can accept new documents.
      </step>
    </stepper>
  </applies-item>

  <applies-item title="serverless: ga" applies-to="Elastic Cloud Serverless: Generally available">
    <stepper>
      <step title="Identify time bounds">
        Search for the lowest and highest `@timestamp` values in the old data stream.
        For example:
        ```json

        {
          "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.
      </step>

      <step title="Create the destination index template">
        Create an index template for the destination TSDS with the [create an index template API](https://www.elastic.co/docs/api/doc/elasticsearch-serverless/operation/operation-indices-put-index-template).
        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

        {
          "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", <1>
              "index.time_series.end_time": "2025-01-01T00:00:00Z", <2>
            },
            "mappings": {
              "properties": {
                "@timestamp": {
                  "type": "date"
                },
                "dimension_field": {
                  "type": "keyword",
                  "time_series_dimension": true
                },
                "metric_field": {
                  "type": "double",
                  "time_series_metric": "gauge"
                }
              }
            }
          }
        }
        ```
        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.
      </step>

      <step title="Create the destination data stream">
        Create a data stream with the [create a data stream API](https://www.elastic.co/docs/api/doc/elasticsearch-serverless/operation/operation-indices-create-data-stream).
        The data stream name must match the `index_patterns` in your index template.
        For example:
        ```json
        ```
      </step>

      <step title="Run the reindex operation">
        Use the [reindex API](https://www.elastic.co/docs/api/doc/elasticsearch-serverless/operation/operation-reindex) to copy documents from the source to the destination data stream.
        For example:
        ```json

        {
          "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](https://www.elastic.co/docs/api/doc/elasticsearch-serverless/operation/operation-indices-get-data-stream) to check that the backing index covers the timestamps you reindexed.
        For example:
        ```json
        ```
        The response lists each backing index and the time range it accepts.
      </step>

      <step title="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

        {
          "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"
                }
              }
            }
          }
        }
        ```
      </step>

      <step title="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](https://www.elastic.co/docs/api/doc/elasticsearch/operation/operation-indices-put-data-lifecycle) API:
        ```json

        {
          "enabled": true,
          "data_retention": "365d" <1>
        }
        ```
        For more details, refer to [Set a data stream's lifecycle](/elastic/docs-content/pull/8715/manage-data/lifecycle/data-stream/tutorial-update-existing-data-stream#set-lifecycle).
      </step>

      <step title="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](https://www.elastic.co/docs/api/doc/elasticsearch-serverless/operation/operation-indices-rollover):
        ```json
        ```
        When this step is complete, the destination data stream can accept new documents.
        Later rollovers happen automatically.
      </step>
    </stepper>
  </applies-item>
</applies-switch>


## Related pages

- [Time series data streams overview](https://docs-v3-preview.elastic.dev/elastic/docs-content/pull/8715/manage-data/data-store/data-streams/time-series-data-stream-tsds)
- [Time-bound indices](https://docs-v3-preview.elastic.dev/elastic/docs-content/pull/8715/manage-data/data-store/data-streams/time-bound-tsds)
- [Reindex indices examples](https://docs-v3-preview.elastic.dev/elastic/elasticsearch/tree/main/reference/elasticsearch/rest-apis/reindex-indices)
- [Reindex with a data stream](/elastic/docs-content/pull/8715/manage-data/data-store/data-streams/use-data-stream#reindex-with-a-data-stream)
- [Load historical data into a time series data stream](https://docs-v3-preview.elastic.dev/elastic/docs-content/pull/8715/manage-data/data-store/data-streams/load-historical-tsds)