---
title: Set up a time series data stream
description: This page shows you how to manually set up a time series data stream (TSDS). Before you create a time series data stream, review Data streams and TSDS...
url: https://www.elastic.co/docs/manage-data/data-store/data-streams/set-up-tsds
products:
  - Elasticsearch
applies_to:
  - Elastic Cloud Serverless: Generally available
  - Elastic Stack: Generally available
---

# Set up a time series data stream
This page shows you how to manually set up a [time series data stream](https://www.elastic.co/docs/manage-data/data-store/data-streams/time-series-data-stream-tsds) (TSDS).

## Before you begin

- Before you create a time series data stream, review [Data streams](https://www.elastic.co/docs/manage-data/data-store/data-streams) and [TSDS concepts](https://www.elastic.co/docs/manage-data/data-store/data-streams/time-series-data-stream-tsds). You can also try the [quickstart](https://www.elastic.co/docs/manage-data/data-store/data-streams/quickstart-tsds) for a hands-on introduction.
- Make sure you have the following permissions:
  - [Cluster privileges](https://www.elastic.co/docs/reference/elasticsearch/security-privileges#privileges-list-cluster)
  - `manage_index_templates` for creating a template to base the TSDS on
- <applies-to>Elastic Stack: Generally available</applies-to> `manage_ilm` if you're using [index lifecycle management](#tsds-ilm-policy)
- [Index privileges](https://www.elastic.co/docs/reference/elasticsearch/security-privileges#privileges-list-indices)
  - `create_doc` and `create_index` for creating or converting a TSDS
- `manage` to [roll over](#convert-existing-data-stream-to-tsds) a TSDS

<note>
  If you're working with OpenTelemetry data, try the [OpenTelemetry quickstarts](https://www.elastic.co/docs/solutions/observability/get-started/opentelemetry/quickstart).
</note>


## Set up a TSDS

<stepper>
  <step title="Create an index lifecycle policy (optional)">
    <applies-to>
      - Elastic Cloud Serverless: Unavailable
      - Elastic Stack: Generally available
    </applies-to>
    In most cases, you can use a [data stream lifecycle](https://www.elastic.co/docs/manage-data/lifecycle/data-stream) to manage your time series data stream. If you're using [data tiers](https://www.elastic.co/docs/manage-data/lifecycle/data-tiers) in Elastic Stack, you can use [index lifecycle management](https://www.elastic.co/docs/manage-data/lifecycle/index-lifecycle-management).
    <dropdown title="Create an ILM policy">
      If you're using Elastic Stack, ILM can help you manage a time series data stream's backing indices. ILM requires an index lifecycle policy.For best results, specify a `max_age` for the `rollover` action in the policy. This ensures the [`timestamp` ranges](https://www.elastic.co/docs/manage-data/data-store/data-streams/time-bound-tsds) for the backing indices are consistent. For example, setting a `max_age` of `1d` for the `rollover` action ensures your backing indices consistently contain one day's worth of data.**Example:**
      ```json

      {
        "policy": {
          "phases": {
            "hot": {
              "actions": {
                "rollover": {
                  "max_age": "1d",
                  "max_primary_shard_size": "50gb"
                }
              }
            }
            // Additional phases (warm, cold, delete) as needed
          }
        }
      }
      ```
    </dropdown>
  </step>

  <step title="Create an index template">
    The structure of a time series data stream is defined by an index template. Create an index template with the following required elements and settings:
    - **Index patterns:** One or more wildcard patterns matching the name of your TSDS, such as `weather-sensors-*`. For best results, use the [data stream naming scheme](/docs/reference/fleet/data-streams#data-streams-naming-scheme).
    - **Data stream object:** The template must include `"data_stream": {}`.
    - **Time series mode:** Set `index.mode: time_series`.
    - **Field mappings:** Define at least one dimension field and typically one or more metric fields:
      - **Dimensions:** To define a dimension, set `time_series_dimension` to `true`. For details, refer to [Dimensions](/docs/manage-data/data-store/data-streams/time-series-data-stream-tsds#time-series-dimension).
      - To define dimensions dynamically, you can use a pass-through object. For details, refer to [Defining sub-fields as time series dimensions](https://www.elastic.co/docs/reference/elasticsearch/mapping-reference/passthrough#passthrough-dimensions).
    - **Metrics:** To define a metric, use the `time_series_metric` mapping parameter. For details, refer to [Metrics](/docs/manage-data/data-store/data-streams/time-series-data-stream-tsds#time-series-metric).
    - **Timestamp** (optional): Define a `date` or `date_nanos` mapping for the `@timestamp` field. If you don't specify a mapping, Elasticsearch maps `@timestamp` as a `date` field with default options.
    - <applies-to>Elastic Cloud Serverless: Unavailable</applies-to> <applies-to>Elastic Stack: Generally available</applies-to> **Lifecycle management**: If you're using Elastic Stack, define a lifecycle to enable automatic rollover and prevent indices from growing too large.
      - Add a `lifecycle` object and specify `"enabled": true`.
    - If you created an ILM policy in [step 1](#tsds-ilm-policy), reference it in the settings with `index.lifecycle.name`.
    - **Settings** (optional): Define any relevant index settings, such as [`index.number_of_replicas`](https://www.elastic.co/docs/reference/elasticsearch/index-settings/index-modules#dynamic-index-number-of-replicas), for the data stream's backing indices.
    - **Priority:** Set the priority higher than `200` to avoid [collisions](/docs/manage-data/data-store/templates#avoid-index-pattern-collisions) with built-in templates.
    **Example index template PUT request:**
    ```json

    {
      "index_patterns": ["metrics-weather_sensors-*"],
      "data_stream": { },
      "template": {
        "settings": {
          "index.mode": "time_series",
          "index.lifecycle.name": "my-lifecycle-policy" <1>
        },
        "lifecycle": { 
          "enabled": true <2>
        },
        "mappings": {
          "properties": {
            "sensor_id": {
              "type": "keyword",
              "time_series_dimension": true
            },
            "location": {
              "type": "keyword",
              "time_series_dimension": true
            },
            "temperature": {
              "type": "half_float",
              "time_series_metric": "gauge"
            },
            "humidity": {
              "type": "half_float",
              "time_series_metric": "gauge"
            },
            "@timestamp": {
              "type": "date"
            }
          }
        }
      },
      "priority": 500,
      "_meta": {
        "description": "Template for my weather sensor data"
      }
    }
    ```

    <important applies-to="Elastic Stack: Generally available">
      Without lifecycle management enabled, time series data streams can grow into very large indices that never roll over. This can lead to performance issues. Always configure lifecycle management for Elastic Stack production deployments.
    </important>

    <dropdown title="Component templates (optional)">
      If you're using component templates with a time series data stream, check the following requirements:
      - Each component template is valid on its own
      - The `index.routing_path` setting and its referenced dimension fields are defined in the same component template
      - The `time_series_dimension` attribute is enabled for fields referenced in `index.routing_path`
    </dropdown>
  </step>

  <step title="Create the time series data stream and add data">
    After creating the index template, you can create a time series data stream by [indexing a document](/docs/manage-data/data-store/data-streams/use-data-stream#add-documents-to-a-data-stream). The TSDS is created automatically when you index the first document, as long as the index name matches the index template pattern. You can use a bulk API request or a POST request.
    <important>
      To test the following `_bulk` example, update the timestamps to within two hours of your current time. Data added to a TSDS must fit the [accepted time range](/docs/manage-data/data-store/data-streams/time-bound-tsds#tsds-accepted-time-range).
    </important>

    ```json

    { "create":{ } }
    { "@timestamp": "2099-05-06T16:21:15.000Z", "sensor_id": "SENSOR-001", "location": "warehouse-A", "temperature": 26.7,"humidity": 49.9 }
    { "create":{ } }
    { "@timestamp": "2099-05-06T16:25:42.000Z", "sensor_id": "SENSOR-002", "location": "warehouse-B", "temperature": 32.4, "humidity": 88.9 }
    ```

    ```json

    {
      "@timestamp": "2099-05-06T16:21:15.000Z",
      "sensor_id": "SENSOR-00002",
      "location": "warehouse-B",
      "temperature": 32.4,
      "humidity": 88.9
    }
    ```
  </step>

  <step title="Verify setup">
    To make sure your time series data stream is working, try some GET requests.View data stream details:
    ```json
    ```
    Check the document count in a time series data stream:
    ```json
    ```
    Query the time series data:
    ```json

    {
      "size": 5,
      "sort": ["@timestamp"]
    }
    ```
  </step>


  ## Advanced setup


  ### Convert an existing data stream to a TSDSYou can convert an existing regular data stream to a TSDS. Follow these steps:

  1. Update your existing index template and component templates (if any) to include time series settings. For Elastic Stack, configure lifecycle management.
  2. Use the [rollover API](https://www.elastic.co/docs/api/doc/elasticsearch/operation/operation-indices-rollover) to manually roll over the existing data stream's write index, to apply the changes you made in step 1:

  ```json
  ```

  <note>
    After the rollover, new backing indices will have time series functionality. Existing backing indices are not affected by the rollover (because their `index.mode` cannot be changed).
  </note>


  ### Secure a time series data streamTo control access to a TSDS, use [index privileges](https://www.elastic.co/docs/reference/elasticsearch/security-privileges#privileges-list-indices). Privileges set on a TSDS also apply to the backing indices.
  For an example, refer to [Data stream privileges](/docs/deploy-manage/users-roles/cluster-or-deployment-auth/granting-privileges-for-data-streams-aliases#data-stream-privileges).

  ## Next stepsNow that you've set up a time series data stream, you can manage and use it like a regular data stream. For more information, refer to:

  - [Use a data stream](https://www.elastic.co/docs/manage-data/data-store/data-streams/use-data-stream) for indexing and searching
  - [Change data stream settings](/docs/manage-data/data-store/data-streams/modify-data-stream#data-streams-change-mappings-and-settings) as needed
  - Query time series data using the ES|QL [`TS` command](https://www.elastic.co/docs/reference/query-languages/esql/commands/ts)
  - Use [data stream APIs](https://www.elastic.co/docs/api/doc/elasticsearch/group/endpoint-data-stream)
</stepper>