# XREAD

> Read new entries from one or more streams, optionally waiting for them.

URL: https://docs.hotkv.com/commands/xread/

```
XREAD [COUNT count] [BLOCK milliseconds] STREAMS key [key ...] id [id ...]
```

- Group: Stream
- Complexity: O(M) for the entries returned
- HotKV Cloud: all plans
- On-Premise: no license needed

`XREAD` returns, for each stream you name, the entries with an ID greater than
the ID you give for it. With `BLOCK`, it waits for new entries when none are
there yet. Use it to tail a stream without consumer groups.

After `STREAMS`, list all keys first and then one ID per key, in the same
order.

## IDs

| ID | Meaning |
| --- | --- |
| `ms-seq` or `ms` | Entries after this ID. |
| `0` | Every entry in the stream. |
| `$` | Only entries added after this call starts (use with `BLOCK`). |
| `+` | The stream's last entry, if it has one. |

## Options

| Option | Effect |
| --- | --- |
| `COUNT count` | At most `count` entries per stream. A count of 0 or less means no limit. |
| `BLOCK milliseconds` | If no stream has entries, wait up to this long for an [XADD](https://docs.hotkv.com/commands/xadd/index.md). `0` waits with no time limit. |

When a blocked call is woken by new entries, it returns entries after the
IDs it was given (for `$`, the last ID the stream had when the call started).

## Return value

Only streams with entries appear in the reply. Each entry is
`[id, [field, value, ...]]`.

| Case | RESP2 | RESP3 |
| --- | --- | --- |
| Entries found | Array of `[key, entries]` pairs | Map of key to entries |
| Nothing found, without `BLOCK` or after the timeout | Nil array | Null |

Error replies:

- `ERR Unbalanced 'xread' list of streams: for each stream key an ID, '+', or '$' must be specified.`
- `ERR The > ID can be specified only when calling XREADGROUP using the GROUP <group> <consumer> option.`
- `ERR Invalid stream ID specified as stream command argument`
- `ERR timeout is negative` and `ERR timeout is not an integer or out of range` for `BLOCK`.
- `ERR syntax error` for an unknown option, and `WRONGTYPE` if a key holds another type.

## Examples

```
127.0.0.1:6379> XADD chat 1700000000000-0 user ana text hi
"1700000000000-0"
127.0.0.1:6379> XADD chat 1700000000001-0 user ben text hello
"1700000000001-0"
127.0.0.1:6379> XREAD COUNT 1 STREAMS chat 0
1) 1) "chat"
   2) 1) 1) "1700000000000-0"
         2) 1) "user"
            2) "ana"
            3) "text"
            4) "hi"
127.0.0.1:6379> XREAD STREAMS chat 1700000000001-0
(nil)
127.0.0.1:6379> XREAD BLOCK 1000 STREAMS chat $
(nil)
(1.00s)
```

## Compatibility

Same as Redis 7 and Valkey 8, plus the `+` ID for reading a stream's last
entry, which Redis added in 7.4.

## See also

[XREADGROUP](https://docs.hotkv.com/commands/xreadgroup/index.md), [XRANGE](https://docs.hotkv.com/commands/xrange/index.md), [XADD](https://docs.hotkv.com/commands/xadd/index.md)