# The Stream Data Type — Redis Pub/Sub & Streams

Source: https://www.skillbyai.com/en/redis-streams/s-model

> Describe stream entries, IDs and how streams differ from lists and Pub/Sub.

## An append-only log in a key

A **stream** is a Redis key holding an **append-only sequence of entries**. Each entry has a unique **ID** and a small set of **field-value pairs**, like a tiny hash: `orderId o-1001 status placed`. IDs have the form **`<milliseconds>-<sequence>`**, such as `1727942712345-0`: the first part is the Redis server time in milliseconds when the entry was added, and the sequence distinguishes entries added in the same millisecond. IDs always increase, so a stream is ordered and you can query by ID ranges, which are effectively **time ranges**. Unlike Pub/Sub, entries **persist** (in memory, and on disk if persistence is enabled) until you trim or delete them, so consumers can read history and resume where they left off. Unlike lists, reading does **not remove** entries, so many independent readers can consume the same stream. Internally, streams use a radix tree of compact listpacks, making them memory-efficient for many small entries.

## Entries with time-based IDs

Each entry has an increasing millisecond-based ID and a few fields; readers keep their own position.

![A horizontal row of small cards, each with a number tab on top and two short lines inside, with two arrow markers above at different positions.](assets/figures/redis-streams/section-4-map.svg) — Figure 4.1 — A stream as an ordered log of entries.

## Adding and reading entries

`*` asks Redis to generate the ID; `-` and `+` mean the smallest and largest IDs.

```bash
XADD orders '*' orderId o-1001 customer c-42 status placed
# returns an ID such as 1727942712345-0
XADD orders '*' orderId o-1002 customer c-7 status placed

XLEN orders                         # number of entries
XRANGE orders - +                   # all entries, oldest first
XRANGE orders - + COUNT 10          # first 10
XREVRANGE orders + - COUNT 5        # newest 5
XRANGE orders 1727942700000 1727942800000   # by time range (ms)
```

## Keep entries small

Streams shine with many small entries. Put identifiers and essential fields in the entry and keep large payloads (documents, images) in a database or object store, referenced by ID.

**Quiz:** What does the first part of a stream entry ID such as 1727942712345-0 represent?

- [ ] A random number
- [ ] The consumer ID
- [x] The millisecond Unix time when the entry was added
- [ ] The entry size in bytes

*Answer:* The millisecond Unix time when the entry was added. Stream IDs combine a millisecond timestamp with a sequence number.
