XADD(3valkey)
β¨ XADD β bestie, let's yeet a message into the stream β¨
okay so this is a page from the Valkey Command Manual (yes, the 3valkey manual, we're fancy) and today's main character is xadd. buckle up π«Ά
π NAME π
xadd β appends a new message to a stream. Creates the key if it doesn't exist. like, if it's not there, it just appears. iconic behavior honestly.
πΈ SYNOPSIS πΈ
XADD key [NOMKSTREAM] [<MAXLEN | MINID> [= | ~] threshold [LIMIT count]]
<* | id> field value [field value ...]
π¦ DESCRIPTION π¦
So the whole vibe is: you append the stream entry you specified to the stream sitting at the key you specified. That's it, that's the job. And if that key doesn't exist yet? Boom β as a side effect of running this command, the key gets created with a stream value. It's giving "make it exist" energy π
But wait, if you're like "no bestie, do NOT make the key for me," you can turn off the creation of the stream's key with the NOMKSTREAM option. You're in control, periodt.
An entry is composed of a list of field-value pairs. And the field-value pairs are stored in the same order they are given by the user β no shuffling, no rearranging, no sneaky alphabetizing. Commands that read the stream, such as XRANGE or XREAD, are guaranteed to return the fields and values exactly in the same order they were added by XADD. Fr fr. Order is sacred here.
XADD is the only Valkey command that can add data to a stream. The one and only. Main character energy, no understudies. That said, there are other commands β like XDEL and XTRIM β that are able to remove data from a stream. So like, XADD puts things in, those take things out. Balance π
β Specifying a Stream ID as an argument β
A stream entry ID identifies a given entry inside a stream. Cute little name tag for each entry.
The XADD command will auto-generate a unique ID for you if the ID argument specified is the * character (asterisk ASCII character). Free ID, on the house π
However β and this is like, only useful in very rare cases, ngl β it is possible to specify a well-formed ID, so that the new entry will be added exactly with the specified ID. You get to pick.
IDs are specified by two numbers separated by a - character:
1526919030474-55
Both quantities are 64-bit numbers. When an ID is auto-generated, the first part is the Unix time in milliseconds of the Valkey instance generating the ID. The second part is just a sequence number and is used in order to distinguish IDs generated in the same millisecond. So like, timestamp + "which one was this in that ms" π
You can also specify an incomplete ID, that consists only of the milliseconds part, which is interpreted as a zero value for sequence part. And to have only the sequence part automatically generated, specify the milliseconds part followed by the - separator and the * character:
> XADD mystream 1526919030474-55 message "Hello,"
"1526919030474-55"
> XADD mystream 1526919030474-* message " World!"
"1526919030474-56"
IDs are guaranteed to be always incremental: if you compare the ID of the entry just inserted it will be greater than any other past ID, so entries are totally ordered inside a stream. Slay, a sorted stream, we love to see it. In order to guarantee this property, if the current top ID in the stream has a time greater than the current local time of the instance, the top entry time will be used instead, and the sequence part of the ID incremented. This may happen when, for instance, the local clock jumps backward, or if after a failover the new primary has a different absolute time. Clocks are messy, but the stream stays ordered π
β οΈ okay listen. When a user specified an explicit ID toXADD, the minimum valid ID is0-1, and the user must specify an ID which is greater than any other ID currently inside the stream, otherwise the command will fail and return an error. No going backwards, bestie. Usually resorting to specific IDs is useful only if you have another system generating unique IDs (for instance an SQL table) and you really want the Stream IDs to match the one of this other system.
π§ Capped streams π§
XADD incorporates the same semantics as the XTRIM command β refer to its documentation page for more information. This allows adding new entries and keeping the stream's size in check with a single call to XADD, effectively capping the stream with an arbitrary threshold. Two birds, one command π¦π¦
Although exact trimming is possible and is the default, due to the internal representation of steams it is more efficient to add an entry and trim stream with XADD using almost exact trimming (the ~ argument). (yes the original says "steams", we're leaving that typo right where it is, it's part of the lore π)
For example, calling XADD in the following form:
XADD mystream MAXLEN ~ 1000 * ... entry fields here ...
Will add a new entry but will also evict old entries so that the stream will contain only 1000 entries, or at most a few tens more. Close enough is good enough β¨
π Additional information about streams π
For further information about streams please check our valkey-streams-intro(7) introduction to Streams document. Go read it, it's the lore drop.
π REPLY π
RESP2
One of the following:
valkey-protocol(7)Bulk string reply: The ID of the added entry. The ID is the one automatically generated if an asterisk (*) is passed as the id argument, otherwise the command just returns the same ID specified by the user during insertion.valkey-protocol(7)Nil reply: if theNOMKSTREAMoption is given and the key doesn't exist.
RESP3
One of the following:
valkey-protocol(7)Bulk string reply: The ID of the added entry. The ID is the one automatically generated if an asterisk (*) is passed as the id argument, otherwise the command just returns the same ID specified by the user during insertion.valkey-protocol(7)Null reply: if theNOMKSTREAMoption is given and the key doesn't exist.
(yeah, RESP2 says Nil and RESP3 says Null β same vibe, different protocol, don't @ me)
π₯ COMPLEXITY π₯
O(1) when adding a new entry, O(N) when trimming where N being the number of entries evicted.
π ACL CATEGORIES π
@fast @stream @write
π HISTORY π
- Available since:
5.0.0 - Changed in
6.2.0: Added theNOMKSTREAMoption,MINIDtrimming strategy and theLIMIToption. - Changed in
7.0.0: Added support for the<ms>-*explicit ID form.
glow-up after glow-up π
πΈ EXAMPLES πΈ
127.0.0.1:6379> XADD mystream * name Sara surname OConnor
"1714701491958-0"
127.0.0.1:6379> XADD mystream * field1 value1 field2 value2 field3 value3
"1714701491968-0"
127.0.0.1:6379> XLEN mystream
(integer) 2
127.0.0.1:6379> XRANGE mystream - +
1) 1) "1714701491958-0"
2) 1) "name"
2) "Sara"
3) "surname"
4) "OConnor"
2) 1) "1714701491968-0"
2) 1) "field1"
2) "value1"
3) "field2"
4) "value2"
5) "field3"
6) "value3"
look at that ordering. look at it. we love a stream that keeps its promises π«Ά
π SEE ALSO π
xack(3valkey), xautoclaim(3valkey), xclaim(3valkey), xdel(3valkey), xgroup(3valkey), xgroup-create(3valkey), xgroup-createconsumer(3valkey), xgroup-delconsumer(3valkey), xgroup-destroy(3valkey), xgroup-help(3valkey), xgroup-setid(3valkey), xinfo(3valkey), xinfo-consumers(3valkey), xinfo-groups(3valkey), xinfo-help(3valkey), xinfo-stream(3valkey), xlen(3valkey), xpending(3valkey), xrange(3valkey), xread(3valkey), xreadgroup(3valkey), xrevrange(3valkey), xsetid(3valkey), xtrim(3valkey)
the whole stream friend group, go say hi π
okay that's the whole page bestie π this was version 9.0.0, dated 2025-10-21, and it's the XADD(3valkey) page. go add an entry, you got this π¦β¨
π¦ where this page comes from
- fedora 44: valkey-doc 9.0.3-2.fc44 Β· CC-BY-SA-4.0
- fedora 44: valkey-doc 9.0.6-1.fc44 Β· CC-BY-SA-4.0
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash on : a language model's rewrite of the original, under its terms