{
  "schema_version": 2,
  "id": "commands/xpending",
  "title": "XPENDING",
  "url": "https://redis.io/docs/latest/commands/xpending/",
  "summary": "Returns the information and entries from a stream consumer group's pending entries list.",
  "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": "eae31cc246a9f49de9d6426e3856aa705cc606ceeb9c0c39ef2e641f180acc9a",
  "sections": [
    {
      "id": "overview",
      "title": "Overview",
      "role": "overview",
      "text": "Fetching data from a stream via a consumer group, and not acknowledging\nsuch data, has the effect of creating *pending entries*. This is\nwell explained in the [`XREADGROUP`](https://redis.io/docs/latest/commands/xreadgroup) command, and even better in our\n[introduction to Redis Streams](https://redis.io/docs/latest/develop/data-types/streams). The [`XACK`](https://redis.io/docs/latest/commands/xack) command\nwill immediately remove the pending entry from the Pending Entries List (PEL)\nsince once a message is successfully processed, there is no longer need\nfor the consumer group to track it and to remember the current owner\nof the message.\n\nThe `XPENDING` command is the interface to inspect the list of pending\nmessages, and is as thus a very important command in order to observe\nand understand what is happening with a streams consumer groups: what\nclients are active, what messages are pending to be consumed, or to see\nif there are idle messages. Moreover this command, together with [`XCLAIM`](https://redis.io/docs/latest/commands/xclaim)\nis used in order to implement recovering of consumers that are failing\nfor a long time, and as a result certain messages are not processed: a\ndifferent consumer can claim the message and continue. This is better\nexplained in the [streams intro](https://redis.io/docs/latest/develop/data-types/streams) and in the\n[`XCLAIM`](https://redis.io/docs/latest/commands/xclaim) command page, and is not covered here."
    },
    {
      "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>group</code></summary>\n\nThe consumer group name.\n\n</details>"
    },
    {
      "id": "optional-arguments",
      "title": "Optional arguments",
      "role": "parameters",
      "text": "With no optional arguments, `XPENDING` returns a summary. Providing `start`, `end`, and `count` returns the extended (detailed) form.\n\n<details open><summary><code>IDLE min-idle-time</code></summary>\n\nFilter to messages that have been idle for at least this long, in milliseconds.\n\n</details>\n\n<details open><summary><code>start</code></summary>\n\nThe start of the ID range to inspect, 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 to inspect, inclusive. Use `+` for the greatest ID.\n\n</details>\n\n<details open><summary><code>count</code></summary>\n\nThe maximum number of messages to return.\n\n</details>\n\n<details open><summary><code>consumer</code></summary>\n\nFilter to messages owned by the given consumer.\n\n</details>"
    },
    {
      "id": "details",
      "title": "Details",
      "role": "content",
      "text": ""
    },
    {
      "id": "summary-form-of-xpending",
      "title": "Summary form of XPENDING",
      "role": "content",
      "text": "When `XPENDING` is called with just a key name and a consumer group\nname, it just outputs a summary about the pending messages in a given\nconsumer group. In the following example, we create a consumer group and\nimmediately create a pending message by reading from the group with\n[`XREADGROUP`](https://redis.io/docs/latest/commands/xreadgroup).\n\n[code example]\n\nWe expect the pending entries list for the consumer group `group55` to\nhave a message right now: consumer named `consumer-123` fetched the\nmessage without acknowledging its processing. The simple `XPENDING`\nform will give us this information:\n\n[code example]\n\nIn this form, the command outputs the total number of pending messages for this\nconsumer group, which is one, followed by the smallest and greatest ID among the\npending messages, and then list every consumer in the consumer group with\nat least one pending message, and the number of pending messages it has."
    },
    {
      "id": "extended-form-of-xpending",
      "title": "Extended form of XPENDING",
      "role": "content",
      "text": "The summary provides a good overview, but sometimes we are interested in the\ndetails. In order to see all the pending messages with more associated\ninformation we need to also pass a range of IDs, in a similar way we do it with\n[`XRANGE`](https://redis.io/docs/latest/commands/xrange), and a non optional *count* argument, to limit the number\nof messages returned per call:\n\n[code example]\n\nIn the extended form we no longer see the summary information, instead there\nis detailed information for each message in the pending entries list. For\neach message four attributes are returned:\n\n1. The ID of the message.\n2. The name of the consumer that fetched the message and has still to acknowledge it. We call it the current *owner* of the message. For messages that have been released back to the group using [`XNACK`](https://redis.io/docs/latest/commands/xnack), this field will be an empty string.\n3. The number of milliseconds that elapsed since the last time this message was delivered to this consumer.\n4. The number of times this message was delivered.\n\nThe deliveries counter, that is the fourth element in the array, is incremented\nwhen some other consumer *claims* the message with [`XCLAIM`](https://redis.io/docs/latest/commands/xclaim), or when the\nmessage is delivered again via [`XREADGROUP`](https://redis.io/docs/latest/commands/xreadgroup), when accessing the history\nof a consumer in a consumer group (see the [`XREADGROUP`](https://redis.io/docs/latest/commands/xreadgroup) page for more info).\n\nIt is possible to pass an additional argument to the command, in order\nto see the messages having a specific owner:\n\n[code example]\n\nBut in the above case the output would be the same, since we have pending\nmessages only for a single consumer. However what is important to keep in\nmind is that this operation, filtering by a specific consumer, is not\ninefficient even when there are many pending messages from many consumers:\nwe have a pending entries list data structure both globally, and for\nevery consumer, so we can very efficiently show just messages pending for\na single consumer."
    },
    {
      "id": "idle-time-filter",
      "title": "Idle time filter",
      "role": "content",
      "text": "It is also possible to filter pending stream entries by their idle-time,\ngiven in milliseconds (useful for [`XCLAIM`](https://redis.io/docs/latest/commands/xclaim)ing entries that have not been\nprocessed for some time):\n\n[code example]\n\nThe first case will return the first 10 (or less) PEL entries of the entire group\nthat are idle for over 9 seconds, whereas in the second case only those of\n`consumer-123`."
    },
    {
      "id": "exclusive-ranges-and-iterating-the-pel",
      "title": "Exclusive ranges and iterating the PEL",
      "role": "content",
      "text": "The `XPENDING` command allows iterating over the pending entries just like\n[`XRANGE`](https://redis.io/docs/latest/commands/xrange) and [`XREVRANGE`](https://redis.io/docs/latest/commands/xrevrange) allow for the stream's entries. You can do this by\nprefixing the ID of the last-read pending entry with the `(` character that\ndenotes an open (exclusive) range, and proving it to the subsequent call to the\ncommand."
    },
    {
      "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): different data depending on the way XPENDING is called, as explained on this page.\n\n**RESP3:**\n\n* [Array reply](../../develop/reference/protocol-spec#arrays): different data depending on the way XPENDING is called, as explained on this page."
    }
  ],
  "examples": [
    {
      "id": "summary-form-of-xpending-ex0",
      "language": "plaintext",
      "code": "> XGROUP CREATE mystream group55 0-0\nOK\n\n> XREADGROUP GROUP group55 consumer-123 COUNT 1 STREAMS mystream >\n1) 1) \"mystream\"\n   2) 1) 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": "summary-form-of-xpending"
    },
    {
      "id": "summary-form-of-xpending-ex1",
      "language": "plaintext",
      "code": "> XPENDING mystream group55\n1) (integer) 1\n2) 1526984818136-0\n3) 1526984818136-0\n4) 1) 1) \"consumer-123\"\n      2) \"1\"",
      "section_id": "summary-form-of-xpending"
    },
    {
      "id": "extended-form-of-xpending-ex0",
      "language": "plaintext",
      "code": "> XPENDING mystream group55 - + 10\n1) 1) 1526984818136-0\n   2) \"consumer-123\"\n   3) (integer) 196415\n   4) (integer) 1",
      "section_id": "extended-form-of-xpending"
    },
    {
      "id": "extended-form-of-xpending-ex1",
      "language": "plaintext",
      "code": "> XPENDING mystream group55 - + 10 consumer-123",
      "section_id": "extended-form-of-xpending"
    },
    {
      "id": "idle-time-filter-ex0",
      "language": "plaintext",
      "code": "> XPENDING mystream group55 IDLE 9000 - + 10\n> XPENDING mystream group55 IDLE 9000 - + 10 consumer-123",
      "section_id": "idle-time-filter"
    }
  ]
}
