{
  "schema_version": 2,
  "id": "commands/ts.createrule",
  "title": "TS.CREATERULE",
  "url": "https://redis.io/docs/latest/commands/ts.createrule/",
  "summary": "Create a compaction rule.",
  "since": "1.0.0",
  "tags": [
    "docs",
    "develop",
    "stack",
    "oss",
    "rs",
    "rc",
    "oss",
    "kubernetes",
    "clients"
  ],
  "last_updated": "2026-09-18T09:48:54+01:00",
  "page_type": "content",
  "content_hash": "b04280b17be8fef179a02e45b811e729f4b9d9a6d22a37a21869ffa4de484a97",
  "sections": [
    {
      "id": "overview",
      "title": "Overview",
      "role": "overview",
      "text": "> [!NOTE]\n> This command's behavior varies in clustered Redis environments. See the [multi-key operations](https://redis.io/docs/latest/develop/using-commands/multi-key-operations) page for more information.\n\n\n\nCreate a compaction rule\n\n[Examples](#examples)"
    },
    {
      "id": "required-arguments",
      "title": "Required arguments",
      "role": "content",
      "text": "<details open><summary><code>sourceKey</code></summary>\n\nis key name for the source time series.\n</details>\n\n<details open><summary><code>destKey</code></summary> \n\nis key name for destination (compacted) time series. It must be created before `TS.CREATERULE` is called. \n</details>\n\n<details open><summary><code>AGGREGATION aggregator bucketDuration</code></summary> \n\naggregates results into time buckets.\n\n  - `aggregator` takes one of the following aggregation types:\n\n    | `aggregator` | Description                                                     |\n    | ------------ | --------------------------------------------------------------- |\n    | `avg`        | Arithmetic mean of all non-NaN values                           |\n    | `sum`        | Sum of all non-NaN values                                       |\n    | `min`        | Minimum non-NaN value                                           |\n    | `max`        | Maximum non-NaN value                                           |\n    | `range`      | Difference between the maximum and the minimum non-NaN values   |\n    | `count`      | Number of non-NaN values                                        |\n    | `countNaN`   | Number of NaN values (since Redis 8.6)                          |\n    | `countAll`   | Number of values, including NaN and non-NaN (since Redis 8.6)   |\n    | `first`      | The non-NaN value with the lowest timestamp in the bucket       |\n    | `last`       | The non-NaN value with the highest timestamp in the bucket      |\n    | `std.p`      | Population standard deviation of the non-NaN values             |\n    | `std.s`      | Sample standard deviation of the non-NaN values                 |\n    | `var.p`      | Population variance of the non-NaN values                       |\n    | `var.s`      | Sample variance of the non-NaN values                           |\n    | `twa`        | Time-weighted average over the bucket's timeframe (ignores NaN values) (since RedisTimeSeries 1.8) |\n\n  - `bucketDuration` is duration of each bucket, in milliseconds.\n  \n<note><b>Notes</b>\n\n- Only new samples that are added into the source series after the creation of the rule will be aggregated.\n- Calling `TS.CREATERULE` with a nonempty `destKey` may result in inconsistencies between the raw and the compacted data.\n- Explicitly adding samples to a compacted time series (using [`TS.ADD`](https://redis.io/docs/latest/commands/ts.add), [`TS.MADD`](https://redis.io/docs/latest/commands/ts.madd), [`TS.INCRBY`](https://redis.io/docs/latest/commands/ts.incrby), or [`TS.DECRBY`](https://redis.io/docs/latest/commands/ts.decrby)) may result in inconsistencies between the raw and the compacted data. The compaction process may override such samples.\n- If no samples are added to the source time series during a bucket period. no _compacted sample_ is added to the destination time series.\n- The timestamp of a compacted sample added to the destination time series is set to the start timestamp the appropriate compaction bucket. For example, for a 10-minute compaction bucket with no alignment, the compacted samples timestamps are `x:00`, `x:10`, `x:20`, and so on.\n- Deleting `destKey` will cause the compaction rule to be deleted as well.\n\n> [!WARNING]\n> In a clustered environment, you must use [hash tags](https://redis.io/docs/latest/operate/oss_and_stack/reference/cluster-spec#hash-tags) to force `sourceKey` and `destKey` to be stored in the same hash slot. If you don't, Redis may fail to compact the data without displaying any error messages.\n  \n</note>"
    },
    {
      "id": "optional-arguments",
      "title": "Optional arguments",
      "role": "parameters",
      "text": "<details open><summary><code>alignTimestamp</code> (since RedisTimeSeries 1.8)</summary>\n\nensures that there is a bucket that starts exactly at `alignTimestamp` and aligns all other buckets accordingly. It is expressed in milliseconds. The default value is 0: aligned with the Unix epoch.\n\nFor example, if `bucketDuration` is 24 hours (`24 * 3600 * 1000`), setting `alignTimestamp` to 6 hours after the Unix epoch (`6 * 3600 * 1000`) ensures that each bucket’s timeframe is `[06:00 .. 06:00)`.\n</details>"
    },
    {
      "id": "examples",
      "title": "Examples",
      "role": "example",
      "text": "<details open>\n<summary><b>Create a compaction rule</b></summary>\n\nCreate a time series to store the temperatures measured in Tel Aviv.\n\n\n127.0.0.1:6379> TS.CREATE temp:{TLV} LABELS type temp location TLV\nOK\n\n\nNext, create a compacted time series named _dailyAvgTemp_ containing one compacted sample per 24 hours: the time-weighted average of all measurements taken from midnight to next midnight.\n\n\n127.0.0.1:6379> TS.CREATE dailyAvgTemp:{TLV} LABELS type temp location TLV\n127.0.0.1:6379> TS.CREATERULE temp:{TLV} dailyAvgTemp:{TLV} AGGREGATION twa 86400000 \n\n\nNow, also create a compacted time series named _dailyDiffTemp_. This time series will contain one compacted sample per 24 hours: the difference between the minimum and the maximum temperature measured between 06:00 and 06:00 next day.\n Here, 86400000 is the number of milliseconds in 24 hours, 21600000 is the number of milliseconds in 6 hours.\n\n\n127.0.0.1:6379> TS.CREATE dailyDiffTemp:{TLV} LABELS type temp location TLV\n127.0.0.1:6379> TS.CREATERULE temp:{TLV} dailyDiffTemp:{TLV} AGGREGATION range 86400000 21600000\n\n\n</details>"
    },
    {
      "id": "redis-software-and-redis-cloud-compatibility",
      "title": "Redis Software and Redis Cloud compatibility",
      "role": "content",
      "text": "| Redis<br />Software | Redis<br />Cloud | <span style=\"min-width: 9em; display: table-cell\">Notes</span> |\n|:----------------------|:-----------------|:------|\n| <span title=\"Supported\">&#x2705; Supported</span><br /> | <span title=\"Supported\">&#x2705; Flexible & Annual</span><br /><span title=\"Supported\">&#x2705; Free & Fixed</nobr></span> |  |"
    },
    {
      "id": "return-information",
      "title": "Return information",
      "role": "returns",
      "text": "**RESP2:**\n\nOne of the following:\n* [Simple string reply](https://redis.io/docs/latest/develop/reference/protocol-spec#simple-strings): `OK` when the compaction rule is created successfully.\n* [Simple error reply](https://redis.io/docs/latest/develop/reference/protocol-spec#simple-errors) in these cases: invalid arguments, wrong key type, `sourceKey` does not exist, `destKey` does not exist, `sourceKey` is already a destination of a compaction rule, `destKey` is already a source or a destination of a compaction rule, or `sourceKey` and `destKey` are identical.\n\n**RESP3:**\n\nOne of the following:\n* [Simple string reply](https://redis.io/docs/latest/develop/reference/protocol-spec#simple-strings): `OK` when the compaction rule is created successfully.\n* [Simple error reply](https://redis.io/docs/latest/develop/reference/protocol-spec#simple-errors) in these cases: invalid arguments, wrong key type, `sourceKey` does not exist, `destKey` does not exist, `sourceKey` is already a destination of a compaction rule, `destKey` is already a source or a destination of a compaction rule, or `sourceKey` and `destKey` are identical."
    },
    {
      "id": "see-also",
      "title": "See also",
      "role": "related",
      "text": "[`TS.DELETERULE`](https://redis.io/docs/latest/commands/ts.deleterule)"
    },
    {
      "id": "related-topics",
      "title": "Related topics",
      "role": "related",
      "text": "[RedisTimeSeries](https://redis.io/docs/latest/develop/data-types/timeseries)"
    }
  ],
  "examples": []
}
