> ## Documentation Index
> Fetch the complete documentation index at: https://upstash.com/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# XPENDING

> Get pending messages info.

Use `XPENDING` to inspect the entries that a consumer group has delivered but not yet acknowledged.

With only a key and a group, the reply is a summary: how many entries are pending, the lowest and highest pending IDs, and the number of pending entries per consumer. That is the cheap form to poll for monitoring.

The extended form, with a start, an end, and a count, lists the pending entries one by one with the consumer that owns each, how long it has been idle, and how many times it has been delivered. `IDLE` restricts the listing to entries idle for at least the given number of milliseconds, and a consumer name restricts it to one worker.

A high delivery count points at an entry that keeps failing, and a long idle time points at a consumer that died holding work. Both are handed over to another consumer with [`XCLAIM`](/docs/redis/commands/streams/xclaim) or [`XAUTOCLAIM`](/docs/redis/commands/streams/xautoclaim).

## Syntax

```redis theme={"system"}
XPENDING <key> <group>
  [[IDLE <min-idle-time>]
    <start> <end> <count>
    [<consumer>]]
```

## Arguments

| Argument                                                    | Required | Repeatable | Description                                                                                                                                                    |
| ----------------------------------------------------------- | -------- | ---------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `<key>`                                                     | Yes      | No         | Redis key targeted by the command.                                                                                                                             |
| `<group>`                                                   | Yes      | No         | Consumer group name.                                                                                                                                           |
| `[IDLE <min-idle-time>] <start> <end> <count> [<consumer>]` | No       | No         | Extended form: optionally filter by idle time, then give the ID range, the maximum number of entries to return, and optionally a single consumer to report on. |

## Response

The reply reports the result of the operation. Error replies have the same shape in RESP2 and RESP3 and are surfaced as exceptions by the SDKs below.

| Protocol | Reply                                                               |
| -------- | ------------------------------------------------------------------- |
| RESP2    | Four-element summary array, or array of pending-entry detail arrays |
| RESP3    | Four-element summary array, or array of pending-entry detail arrays |

<Note>
  Client libraries often decode bulk strings, maps, sets, and numeric strings into language-native values. The table describes the Redis wire reply.
</Note>

## Examples

TCP examples use the TLS `REDIS_URL` from the Upstash console. REST examples use `UPSTASH_REDIS_REST_URL` and `UPSTASH_REDIS_REST_TOKEN`.

<AccordionGroup>
  <Accordion title="Redis CLI" icon="terminal">
    ```bash theme={"system"}
    XPENDING my-key workers
    ```
  </Accordion>

  <Accordion title="@upstash/redis" icon="node-js" iconType="brands">
    ```ts theme={"system"}
    import { Redis } from "@upstash/redis";

    const redis = Redis.fromEnv();

    const result = await redis.xpending("mystream", "mygroup", "-", "+", 10);
    ```
  </Accordion>

  <Accordion title="upstash_redis" icon="python" iconType="brands">
    ```python theme={"system"}
    from upstash_redis import Redis

    redis = Redis.from_env()
    result = redis.xpending("my-key", "workers")
    print(result)
    ```
  </Accordion>

  <Accordion title="ioredis" icon="node-js" iconType="brands">
    ```ts theme={"system"}
    import Redis from "ioredis";

    const redis = new Redis(process.env.REDIS_URL!);
    const result = await redis.xpending("my-key", "workers");
    console.log(result);
    ```
  </Accordion>

  <Accordion title="node-redis" icon="node-js" iconType="brands">
    ```ts theme={"system"}
    import { createClient } from "redis";

    const client = await createClient({ url: process.env.REDIS_URL })
      .on("error", console.error)
      .connect();
    const result = await client.xPending("my-key", "workers");
    console.log(result);
    ```
  </Accordion>

  <Accordion title="redis-py" icon="python" iconType="brands">
    ```python theme={"system"}
    import os
    import redis

    client = redis.from_url(os.environ["REDIS_URL"])
    result = client.xpending("my-key", "workers")
    print(result)
    ```
  </Accordion>

  <Accordion title="go-redis" icon="golang" iconType="brands">
    ```go theme={"system"}
    package main

    import (
        "context"
        "fmt"
        "os"

        "github.com/redis/go-redis/v9"
    )

    func main() {
        opts, err := redis.ParseURL(os.Getenv("REDIS_URL"))
        if err != nil {
            panic(err)
        }
        client := redis.NewClient(opts)
        result, err := client.XPending(context.Background(), "my-key", "workers").Result()
        if err != nil {
            panic(err)
        }
        fmt.Println(result)
    }
    ```
  </Accordion>

  <Accordion title="jedis" icon="java" iconType="brands">
    ```java theme={"system"}
    import java.net.URI;

    import redis.clients.jedis.Jedis;

    try (Jedis jedis = new Jedis(new URI(System.getenv("REDIS_URL")))) {
      Object result = jedis.xpending("my-key", "workers");
      System.out.println(result);
    }
    ```
  </Accordion>

  <Accordion title="redis-rs" icon="rust" iconType="brands">
    ```rust theme={"system"}
    use redis::TypedCommands;

    fn main() -> redis::RedisResult<()> {
        let url = std::env::var("REDIS_URL").expect("REDIS_URL is not set");
        let client = redis::Client::open(url)?;
        let mut connection = client.get_connection()?;

        let result = connection.xpending("my-key", "workers")?;
        println!("{result:?}");
        Ok(())
    }
    ```
  </Accordion>
</AccordionGroup>


## Related topics

- [XPENDING](/docs/redis/sdks/ts/commands/stream/xpending.md)
- [XDEL](/docs/redis/commands/streams/xdel.md)
- [XAUTOCLAIM](/docs/redis/commands/streams/xautoclaim.md)
- [XREADGROUP](/docs/redis/commands/streams/xreadgroup.md)
