VALKEY-KEY-SPECS(7)
π NAME π
valkey-key-specs(7) β Command key specifications
okay so bestie, you're reading the valkey-key-specs(7) manual page, and it's literally all about command key specifications. π
π DESCRIPTION π
Many of the commands in Valkey accept key names as input arguments. The 9th element in the reply of COMMAND (and COMMAND INFO) is an array that consists of the commandβs key specifications. β¨
A key specification describes a rule for extracting the names of one or more keys from the arguments of a given command. Key specifications provide a robust and flexible mechanism, compared to the first key, last key and step scheme employed until Redis OSS 7.0. Before introducing these specifications, Valkey clients had no trivial programmatic means to extract key names for all commands.
Cluster-aware Valkey clients had to have the keysβ extraction logic hard-coded in the cases of commands such as EVAL and ZUNIONSTORE that rely on a numkeys argument or SORT and its many clauses. Alternatively, the COMMAND GETKEYS can be used to achieve a similar extraction effect but at a higher latency. π
A Valkey client isnβt obligated to support key specifications. It can continue using the legacy first key, last key and step scheme along with the command(3valkey) that remain unchanged.
However, a Valkey client that implements key specifications support can consolidate most of its keysβ extraction logic. Even if the client encounters an unfamiliar type of key specification, it can always revert to the COMMAND GETKEYS command. π«Ά
That said, most cluster-aware clients only require a single key name to perform correct command routing, so it is possible that although a command features one unfamiliar specification, its other specification may still be usable by the client.
Key specifications are maps with the following keys:
begin_search:: the starting index for keysβ extraction.find_keys: the rule for identifying the keys relative to the BS.notes: notes about this key spec, if there are any.flags: indicate the type of data access.
β¨ begin_search β¨
The begin_search value of a specification informs the client of the extractionβs beginning. The value is a map. There are three types of begin_search:
index: key name arguments begin at a constant index.keyword: key names start after a specific keyword (token).unknown: an unknown type of specification - see theincompleteflag section for more details.
π index π
The index type of begin_search indicates that input keys appear at a constant index. It is a map under the spec key with a single key:
index: the 0-based index from which the client should start extracting key names.
πΈ keyword πΈ
The keyword type of begin_search means a literal token precedes key name arguments. It is a map under the spec with two keys:
keyword: the keyword (token) that marks the beginning of key name arguments.startfrom: an index to the arguments array from which the client should begin searching. This can be a negative value, which means the search should start from the end of the argumentsβ array, in reverse order. For example,-2βs meaning is to search reverse from the penultimate argument.
More examples of the keyword search type include:
SEThas abegin_searchspecification of typeindexwith a value of1.XREADhas abegin_searchspecification of typekeywordwith the valuesSTREAMSand1askeywordandstartfrom, respectively.MIGRATEhas astart_searchspecification of typekeywordwith the values ofKEYSand-2.
π₯ find_keys π₯
The find_keys value of a key specification tells the client how to continue the search for key names. find_keys has three possible types:
range: keys stop at a specific index or relative to the last argument.keynum: an additional argument specifies the number of input keys.unknown: an unknown type of specification - see theincompleteflag section for more details.
π range π
The range type of find_keys is a map under the spec key with three keys:
lastkey: the index, relative tobegin_search, of the last key argument. This can be a negative value, in which case it isnβt relative. For example,-1indicates to keep extracting keys until the last argument,-2until one before the last, and so on.keystep: the number of arguments that should be skipped, after finding a key, to find the next one.limit: iflastkeyis has the value of-1, we use thelimitto stop the search by a factor.0and1mean no limit.2means half of the remaining arguments,3means a third, and so on.
π keynum π
The keynum type of find_keys is a map under the spec key with three keys:
keynumidx: the index, relative tobegin_search, of the argument containing the number of keys.firstkey: the index, relative tobegin_search, of the first key. This is usually the next argument afterkeynumidx, and its value, in this case, is greater by one.keystep: Tthe number of arguments that should be skipped, after finding a key, to find the next one.
Examples:
- The
SETcommand has arangeof0,1and0. - The
MSETcommand has arangeof-1,2and0. - The
XREADcommand has arangeof-1,1and2. - The
ZUNIONcommand has astart_searchtypeindexwith the value1, andfind_keysof typekeynumwith values of0,1and1.
Note: this isnβt a perfect solution as the module writers can come up with anything. However, this mechanism should allow the extraction of key name arguments for the vast majority of commands.
π¦ NOTES π¦
Notes about non-obvious key specs considerations, if applicable.
π flags π
A key specification can have additional flags that provide more details about the key. These flags are divided into three groups, as described below.
β¨ Access type flags β¨
The following flags declare the type of access the command uses to a keyβs value or its metadata. A keyβs metadata includes LRU/LFU counters, type, and cardinality. These flags do not relate to the reply sent back to the client.
Every key specification has precisely one of the following flags:
RWβ the read-write flag. The command modifies the data stored in the value of the key or its metadata. This flag marks every operation that isnβt distinctly a delete, an overwrite, or read-only.ROβ the read-only flag. The command only reads the value of the key (although it doesnβt necessarily return it).OWβ the overwrite flag. The command overwrites the data stored in the value of the key.RMβ the remove flag. The command deletes the key.
π Logical operation flags π
The following flags declare the type of operations performed on the data stored as the keyβs value and its TTL (if any), not the metadata. These flags describe the logical operation that the command executes on data, driven by the input arguments. The flags do not relate to modifying or returning metadata (such as a keyβs type, cardinality, or existence).
Every key specification may include the following flag:
accessβ the access flag. This flag indicates that the command returns, copies, or somehow uses the userβs data thatβs stored in the key.
In addition, the specification may include precisely one of the following:
updateβ the update flag. The command updates the data stored in the keyβs value. The new value may depend on the old value. This flag marks every operation that isnβt distinctly an insert or a delete.insertβ the insert flag. The command only adds data to the value; existing data isnβt modified or deleted.deleteβ the delete flag. The command explicitly deletes data from the value stored at the key.
πΈ Miscellaneous flags πΈ
Key specifications may have the following flags:
not_keyβ this flag indicates that the specified argument isnβt a key. This argument is treated the same as a key when computing which slot a command should be assigned to for Valkey cluster. For all other purposes this argument should not be considered a key.incompleteβ this flag is explained below.variable_flagsβ this flag is explained below.
π incomplete π
Some commands feature exotic approaches when it comes to specifying their keys, which makes extraction difficult. Consider, for example, what would happen with a call to MIGRATE that includes the literal string KEYS as an argument to its AUTH clause. Our key specifications would miss the mark, and extraction would begin at the wrong index.
Thus, we recognize that key specifications are incomplete and may fail to extract all keys. However, we assure that even incomplete specifications never yield the wrong names of keys, providing that the command is syntactically correct.
In the case of MIGRATE, the search begins at the end (startfrom has the value of -1). If and when we encounter a key named KEYS, weβll only extract the subset of the key name arguments after it. Thatβs why MIGRATE has the incomplete flag in its key specification.
Another case of incompleteness is the SORT command. Here, the begin_search and find_keys are of type unknown. The client should revert to calling the COMMAND GETKEYS command to extract key names from the arguments, short of implementing it natively. The difficulty arises, for example, because the string STORE is both a keyword (token) and a valid literal argument for SORT.
Note: the only commands with incomplete key specifications areSORTandMIGRATE. We donβt expect the addition of such commands in the future.
π«Ά variable_flags π«Ά
In some commands, the flags for the same key name argument can depend on other arguments. For example, consider the SET command and its optional GET argument. Without the GET argument, SET is write-only, but it becomes a read and write command with it. When this flag is present, it means that the key specification flags cover all possible options, but the effective flags depend on other arguments.
π EXAMPLES π
okay bestie, this is the part where it stops being theory and gets real. π here's what the key specs actually look like when they come back at you β nested arrays and all. don't panic at the nesting, it's giving very "onion but make it data", and we're gonna walk through two of them. π§ β¨
πΈ SET's key specifications πΈ
SET is the extrovert of the family β it writes, it reads, it updates. look at all those flags, she's booked and busy. π₯
1) 1) "flags"
2) 1) RW
2) access
3) update
3) "begin_search"
4) 1) "type"
2) "index"
3) "spec"
4) 1) "index"
2) (integer) 1
5) "find_keys"
6) 1) "type"
2) "range"
3) "spec"
4) 1) "lastkey"
2) (integer) 0
3) "keystep"
4) (integer) 1
5) "limit"
6) (integer) 0
so what's the tea? π΅ the flags are RW, access and update β meaning this command both touches the keys and changes them, iconic behavior honestly. the begin_search is type index with index set to (integer) 1, so we know exactly where the keys start. then find_keys is type range, with lastkey = (integer) 0, keystep = (integer) 1, and limit = (integer) 0. simple, clean, no cap. π
π¦ ZUNION's key specifications π¦
now ZUNION β she's a read-only queen, she just looks. different vibe entirely, and the find_keys strategy is lowkey a whole different beast. π
1) 1) "flags"
2) 1) RO
2) access
3) "begin_search"
4) 1) "type"
2) "index"
3) "spec"
4) 1) "index"
2) (integer) 1
5) "find_keys"
6) 1) "type"
2) "keynum"
3) "spec"
4) 1) "keynumidx"
2) (integer) 0
3) "firstkey"
4) (integer) 1
5) "keystep"
6) (integer) 1
see the difference? π the flags are RO and access β read-only, she's not here to change anything, just to observe. periodt. the begin_search is still type index with index = (integer) 1, same as before. BUT the find_keys is type keynum this time, and the spec is a whole different shape: keynumidx = (integer) 0, firstkey = (integer) 1, and keystep = (integer) 1.
π the glow-up here:rangesays "the keys run from here to there", whilekeynumsays "the number of keys is in the command itself, go count them". two totally different ways to find your keys, and both are valid. iykyk. π
and that's the whole vibe check, bestie β nested arrays decoded, flags understood, range vs keynum distinguished. you ate that. πβ¨
and that's a wrap on VALKEY-KEY-SPECS(7) π« β this lil masterpiece is from the 9.0.0 era, dated 2025-10-21, and yes the page really does sign itself VALKEY-KEY-SPECS(7) at the bottom like a little signature. go forth and inspect those key specs, you gorgeous nerd. π«Άπ
π¦ 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