# XADD

> Append an entry to a stream, optionally trimming the stream in the same call.

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

```
XADD key [NOMKSTREAM] [IDMP producer iid | IDMPAUTO producer] [MAXLEN | MINID [= | ~] threshold [LIMIT count]] <* | id> field value [field value ...]
```

- Group: Stream
- Complexity: O(1) to add, plus O(N) for the entries a trim removes
- HotKV Cloud: all plans
- On-Premise: no license needed

`XADD` appends one entry, made of one or more field-value pairs, to the stream
at `key` and returns the entry's ID. The stream is created when the key does
not exist, unless you pass `NOMKSTREAM`.

## Entry IDs

An ID has the form `ms-seq`: a Unix time in milliseconds and a sequence
number. Every new ID must be greater than the stream's last ID.

| ID argument | Meaning |
| --- | --- |
| `*` | The server picks the ID from its clock, with a sequence that keeps IDs increasing. |
| `ms-*` | You choose the time; the server picks the next free sequence for it. |
| `ms-seq` | You choose the whole ID. |
| `ms` | Same as `ms-0`. |

`0-0` (and `0`) is never accepted.

## Options

| Option | Effect |
| --- | --- |
| `NOMKSTREAM` | Do not create the stream: if the key does not exist, nothing is added and the reply is nil. |
| `IDMP producer iid` | Add the entry only once. If this producer already added an entry with this `iid` and the stream still remembers it, nothing is added and the reply is the ID of the earlier entry. |
| `IDMPAUTO producer` | The same, with the entry's field names and values taken as the `iid`, so you do not choose one. |
| `MAXLEN threshold` | After adding, trim the stream to at most `threshold` entries (oldest first). |
| `MINID threshold` | After adding, remove entries with an ID lower than `threshold`. |
| `=` | Trim exactly to the threshold (the default). |
| `~` | Approximate trim: the server may leave some extra entries so the trim is cheaper. |
| `LIMIT count` | With `~`, remove at most `count` entries in this call (`0` means no cap). |

`MAXLEN` and `MINID` cannot be combined. `LIMIT` needs a trimming strategy and
the `~` modifier. Without `LIMIT`, an approximate trim removes at most 100
times `stream-node-max-entries` entries per call (10,000 with the default
setting). The options must come before the ID.

`IDMP` and `IDMPAUTO` can be given once and need the ID `*`: an ID you choose is
refused. The stream remembers the `iid`s of each producer for `IDMP-DURATION`
seconds (100 by default) and keeps the latest `IDMP-MAXSIZE` of them (100 by
default). [XCFGSET](https://docs.hotkv.com/commands/xcfgset/index.md) changes both limits. A retry that comes
after the time or beyond the count adds a second entry, so size the limits to
cover your longest retry. [XINFO STREAM](https://docs.hotkv.com/commands/xinfo-stream/index.md) shows the limits
and how many IDs and producers the stream holds.

## Return value

| Case | RESP2 | RESP3 |
| --- | --- | --- |
| Entry added | Bulk string: the new ID | Bulk string: the new ID |
| `NOMKSTREAM` and the key does not exist | Nil bulk string | Null |
| `IDMP` or `IDMPAUTO` and the ID is already known | Bulk string: the ID of the entry added earlier | Bulk string: the ID of the entry added earlier |

Error replies:

- `ERR Invalid stream ID specified as stream command argument` for an ID that does not parse.
- `ERR The ID specified in XADD must be greater than 0-0`
- `ERR The ID specified in XADD is equal or smaller than the target stream top item`
- `ERR The MAXLEN argument must be >= 0.` and `ERR The LIMIT argument must be >= 0.`
- `ERR syntax error, MAXLEN and MINID options at the same time are not compatible`
- `ERR syntax error, LIMIT cannot be used without the special ~ option`
- `ERR syntax error, IDMP/IDMPAUTO can be used only with auto-generated IDs` when an ID other than `*` is given with them.
- `ERR syntax error, IDMP requires a non-empty producer ID`, `ERR syntax error, IDMPAUTO requires a non-empty producer ID` and `ERR syntax error, IDMP requires a non-empty idempotent ID` for an empty value, and `ERR syntax error, IDMP/IDMPAUTO specified multiple times` for a second use.
- `ERR wrong number of arguments for 'xadd' command` when field-value pairs are missing or unbalanced.
- `WRONGTYPE` if the key holds another type.

## Examples

```
127.0.0.1:6379> XADD orders 1700000000000-0 item book qty 1
"1700000000000-0"
127.0.0.1:6379> XADD orders 1700000000000-* item pen qty 3
"1700000000000-1"
127.0.0.1:6379> XADD orders 1699999999999-0 item cup qty 2
(error) ERR The ID specified in XADD is equal or smaller than the target stream top item
127.0.0.1:6379> XADD orders MAXLEN 1 1700000000001-0 item lamp qty 1
"1700000000001-0"
127.0.0.1:6379> XLEN orders
(integer) 1
127.0.0.1:6379> XADD missing NOMKSTREAM * a 1
(nil)
127.0.0.1:6379> XADD checkouts IDMP shop-1 order-77 * item book qty 1
"1791090396756-0"
127.0.0.1:6379> XADD checkouts IDMP shop-1 order-77 * item book qty 1
"1791090396756-0"
127.0.0.1:6379> XADD checkouts IDMPAUTO shop-1 * item cup qty 2
"1791090396756-1"
127.0.0.1:6379> XADD checkouts IDMPAUTO shop-1 * item cup qty 2
"1791090396756-1"
127.0.0.1:6379> XADD checkouts IDMP shop-2 order-77 * item lamp qty 1
"1791090396756-2"
127.0.0.1:6379> XLEN checkouts
(integer) 3
127.0.0.1:6379> XADD checkouts IDMP shop-1 order-79 1700000000000-1 item mug qty 1
(error) ERR syntax error, IDMP/IDMPAUTO can be used only with auto-generated IDs
```

## Compatibility

Same options, ID rules and replies as Redis 7 and Valkey 8. `IDMP` and `IDMPAUTO` are
Redis 8.6's idempotent-producer options.

## See also

[XRANGE](https://docs.hotkv.com/commands/xrange/index.md), [XREAD](https://docs.hotkv.com/commands/xread/index.md), [XTRIM](https://docs.hotkv.com/commands/xtrim/index.md),
[XLEN](https://docs.hotkv.com/commands/xlen/index.md), [XDEL](https://docs.hotkv.com/commands/xdel/index.md), [XSETID](https://docs.hotkv.com/commands/xsetid/index.md)