{
  "schema_version": 2,
  "id": "commands/xrange",
  "title": "XRANGE",
  "url": "https://redis.io/docs/latest/commands/xrange/",
  "summary": "Returns the messages from a stream within a range of IDs.",
  "since": "5.0.0",
  "tags": [
    "docs",
    "develop",
    "stack",
    "oss",
    "rs",
    "rc",
    "oss",
    "kubernetes",
    "clients"
  ],
  "last_updated": "2026-09-18T16:45:25+01:00",
  "page_type": "content",
  "content_hash": "39794072a6d7bbb32ab8f9e039f2284565cd8b2bab2c353f86ec8a1b465cdd0a",
  "sections": [
    {
      "id": "overview",
      "title": "Overview",
      "role": "overview",
      "text": "The command returns the stream entries matching a given range of IDs.\nThe range is specified by a minimum and maximum ID. All the entries having\nan ID between the two specified or exactly one of the two IDs specified\n(closed interval) are returned.\n\nThe `XRANGE` command has a number of applications:\n\n* Returning items in a specific time range. This is possible because\n  Stream IDs are [related to time](https://redis.io/docs/latest/develop/data-types/streams).\n* Iterating a stream incrementally, returning just\n  a few items at every iteration. However it is semantically much more\n  robust than the [`SCAN`](https://redis.io/docs/latest/commands/scan) family of functions.\n* Fetching a single entry from a stream, providing the ID of the entry\n  to fetch two times: as start and end of the query interval.\n\nThe command also has a reciprocal command returning items in the\nreverse order, called [`XREVRANGE`](https://redis.io/docs/latest/commands/xrevrange), which is otherwise identical."
    },
    {
      "id": "required-arguments",
      "title": "Required arguments",
      "role": "content",
      "text": "<details open><summary><code>key</code></summary>\n\nThe stream key.\n\n</details>\n\n<details open><summary><code>start</code></summary>\n\nThe start of the ID range, inclusive. Use `-` for the smallest ID.\n\n</details>\n\n<details open><summary><code>end</code></summary>\n\nThe end of the ID range, inclusive. Use `+` for the greatest ID.\n\n</details>"
    },
    {
      "id": "optional-arguments",
      "title": "Optional arguments",
      "role": "parameters",
      "text": "<details open><summary><code>COUNT count</code></summary>\n\nThe maximum number of entries to return.\n\n</details>"
    },
    {
      "id": "examples",
      "title": "Examples",
      "role": "example",
      "text": "redis> XADD writers * name Virginia surname Woolf\n\"1784722084364-0\"\nredis> XADD writers * name Jane surname Austen\n\"1784722084364-1\"\nredis> XADD writers * name Toni surname Morrison\n\"1784722084365-0\"\nredis> XADD writers * name Agatha surname Christie\n\"1784722084366-0\"\nredis> XADD writers * name Ngozi surname Adichie\n\"1784722084366-1\"\nredis> XLEN writers\n(integer) 5\nredis> XRANGE writers - + COUNT 2\n1) 1) \"1784722084364-0\"\n   2) 1) \"name\"\n      2) \"Virginia\"\n      3) \"surname\"\n      4) \"Woolf\"\n2) 1) \"1784722084364-1\"\n   2) 1) \"name\"\n      2) \"Jane\"\n      3) \"surname\"\n      4) \"Austen\""
    },
    {
      "id": "details",
      "title": "Details",
      "role": "content",
      "text": ""
    },
    {
      "id": "--and--special-ids",
      "title": "`-` and `+` special IDs",
      "role": "content",
      "text": "The `-` and `+` special IDs mean respectively the minimum ID possible\nand the maximum ID possible inside a stream, so the following command\nwill just return every entry in the stream:\n\n[code example]\n\nThe `-` and `+` special IDs mean, respectively, the minimal and maximal range IDs,\nhowever they are nicer to type."
    },
    {
      "id": "incomplete-ids",
      "title": "Incomplete IDs",
      "role": "content",
      "text": "Stream IDs are composed of two parts, a Unix millisecond time stamp and a\nsequence number for entries inserted in the same millisecond. It is possible\nto use `XRANGE` specifying just the first part of the ID, the millisecond time,\nlike in the following example:\n\n[code example]\n\nIn this case, `XRANGE` will auto-complete the start interval with `-0`\nand end interval with `-18446744073709551615`, in order to return all the\nentries that were generated between a given millisecond and the end of\nthe other specified millisecond. This also means that repeating the same\nmillisecond two times, we get all the entries within such millisecond,\nbecause the sequence number range will be from zero to the maximum.\n\nUsed in this way `XRANGE` works as a range query command to obtain entries\nin a specified time. This is very handy in order to access the history\nof past events in a stream."
    },
    {
      "id": "exclusive-ranges",
      "title": "Exclusive ranges",
      "role": "content",
      "text": "The range is close (inclusive) by default, meaning that the reply can include\nentries with IDs matching the query's start and end intervals. It is possible\nto specify an open interval (exclusive) by prefixing the ID with the\ncharacter `(`. This is useful for iterating the stream, as explained below."
    },
    {
      "id": "returning-a-maximum-number-of-entries",
      "title": "Returning a maximum number of entries",
      "role": "returns",
      "text": "Using the **COUNT** option it is possible to reduce the number of entries\nreported. This is a very important feature even if it may look marginal,\nbecause it allows, for instance, to model operations such as *give me\nthe entry greater or equal to the following*:\n\n[code example]\n\nIn the above case the entry `1526985054069-0` exists, otherwise the server\nwould have sent us the next one. Using `COUNT` is also the base in order to\nuse `XRANGE` as an iterator."
    },
    {
      "id": "iterating-a-stream",
      "title": "Iterating a stream",
      "role": "content",
      "text": "In order to iterate a stream, we can proceed as follows. Let's assume that\nwe want two elements per iteration. We start fetching the first two\nelements, which is trivial:\n\n[code example]\n\nThen instead of starting the iteration again from `-`, as the start\nof the range we use the entry ID of the *last* entry returned by the\nprevious `XRANGE` call as an exclusive interval.\n\nThe ID of the last entry is `1526985685298-0`, so we just prefix it\nwith a '(', and continue our iteration:\n\n[code example]\n\nAnd so forth. Eventually this will allow to visit all the entries in the\nstream. Obviously, we can start the iteration from any ID, or even from\na specific time, by providing a given incomplete start ID. Moreover, we\ncan limit the iteration to a given ID or time, by providing an end\nID or incomplete ID instead of `+`.\n\nThe command [`XREAD`](https://redis.io/docs/latest/commands/xread) is also able to iterate the stream.\nThe command [`XREVRANGE`](https://redis.io/docs/latest/commands/xrevrange) can iterate the stream reverse, from higher IDs\n(or times) to lower IDs (or times).\n\n#### Iterating with earlier versions of Redis\n\nWhile exclusive range intervals are only available from Redis 6.2, it is still\npossible to use a similar stream iteration pattern with earlier versions. You\nstart fetching from the stream the same way as described above to obtain the\nfirst entries.\n\nFor the subsequent calls, you'll need to programmatically advance the last\nentry's ID returned. Most Redis client should abstract this detail, but the\nimplementation can also be in the application if needed. In the example above,\nthis means incrementing the sequence of `1526985685298-0` by one, from 0 to 1.\nThe second call would, therefore, be:\n\n[code example]\n\nAlso, note that once the sequence part of the last ID equals \n18446744073709551615, you'll need to increment the timestamp and reset the\nsequence part to 0. For example, incrementing the ID\n`1526985685298-18446744073709551615` should result in `1526985685299-0`.\n\nA symmetrical pattern applies to iterating the stream with [`XREVRANGE`](https://redis.io/docs/latest/commands/xrevrange). The\nonly difference is that the client needs to decrement the ID for the subsequent\ncalls. When decrementing an ID with a sequence part of 0, the timestamp needs\nto be decremented by 1 and the sequence set to 18446744073709551615."
    },
    {
      "id": "fetching-single-items",
      "title": "Fetching single items",
      "role": "content",
      "text": "If you look for an `XGET` command you'll be disappointed because `XRANGE`\nis effectively the way to go in order to fetch a single entry from a\nstream. All you have to do is to specify the ID two times in the arguments\nof XRANGE:\n\n[code example]"
    },
    {
      "id": "additional-information-about-streams",
      "title": "Additional information about streams",
      "role": "content",
      "text": "For further information about Redis streams please see\n[Introduction to Redis Streams](https://redis.io/docs/latest/develop/data-types/streams)."
    },
    {
      "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; Standard</span><br /><span title=\"Supported\"><nobr>&#x2705; Active-Active</nobr></span> | <span title=\"Supported\">&#x2705; Standard</span><br /><span title=\"Supported\"><nobr>&#x2705; Active-Active</nobr></span> |  |"
    },
    {
      "id": "return-information",
      "title": "Return information",
      "role": "returns",
      "text": "**RESP2:**\n\n[Array reply](../../develop/reference/protocol-spec#arrays): a list of stream entries with IDs matching the specified range.\n\n**RESP3:**\n\n[Array reply](../../develop/reference/protocol-spec#arrays): a list of stream entries with IDs matching the specified range."
    }
  ],
  "examples": [
    {
      "id": "--and--special-ids-ex0",
      "language": "plaintext",
      "code": "> XRANGE somestream - +\n1) 1) 1526985054069-0\n   2) 1) \"duration\"\n      2) \"72\"\n      3) \"event-id\"\n      4) \"9\"\n      5) \"user-id\"\n      6) \"839248\"\n2) 1) 1526985069902-0\n   2) 1) \"duration\"\n      2) \"415\"\n      3) \"event-id\"\n      4) \"2\"\n      5) \"user-id\"\n      6) \"772213\"\n... other entries here ...",
      "section_id": "--and--special-ids"
    },
    {
      "id": "incomplete-ids-ex0",
      "language": "plaintext",
      "code": "> XRANGE somestream 1526985054069 1526985055069",
      "section_id": "incomplete-ids"
    },
    {
      "id": "returning-a-maximum-number-of-entries-ex0",
      "language": "plaintext",
      "code": "> XRANGE somestream 1526985054069-0 + COUNT 1\n1) 1) 1526985054069-0\n   2) 1) \"duration\"\n      2) \"72\"\n      3) \"event-id\"\n      4) \"9\"\n      5) \"user-id\"\n      6) \"839248\"",
      "section_id": "returning-a-maximum-number-of-entries"
    },
    {
      "id": "iterating-a-stream-ex0",
      "language": "plaintext",
      "code": "> XRANGE writers - + COUNT 2\n1) 1) 1526985676425-0\n   2) 1) \"name\"\n      2) \"Virginia\"\n      3) \"surname\"\n      4) \"Woolf\"\n2) 1) 1526985685298-0\n   2) 1) \"name\"\n      2) \"Jane\"\n      3) \"surname\"\n      4) \"Austen\"",
      "section_id": "iterating-a-stream"
    },
    {
      "id": "iterating-a-stream-ex1",
      "language": "plaintext",
      "code": "> XRANGE writers (1526985685298-0 + COUNT 2\n1) 1) 1526985691746-0\n   2) 1) \"name\"\n      2) \"Toni\"\n      3) \"surname\"\n      4) \"Morrison\"\n2) 1) 1526985712947-0\n   2) 1) \"name\"\n      2) \"Agatha\"\n      3) \"surname\"\n      4) \"Christie\"",
      "section_id": "iterating-a-stream"
    },
    {
      "id": "iterating-a-stream-ex2",
      "language": "plaintext",
      "code": "> XRANGE writers 1526985685298-1 + COUNT 2\n1) 1) 1526985691746-0\n   2) 1) \"name\"\n      2) \"Toni\"\n...",
      "section_id": "iterating-a-stream"
    },
    {
      "id": "fetching-single-items-ex0",
      "language": "plaintext",
      "code": "> XRANGE mystream 1526984818136-0 1526984818136-0\n1) 1) 1526984818136-0\n   2) 1) \"duration\"\n      2) \"1532\"\n      3) \"event-id\"\n      4) \"5\"\n      5) \"user-id\"\n      6) \"7782813\"",
      "section_id": "fetching-single-items"
    }
  ]
}
