VALKEY-VALKEY-JSON(7)
π¦ NAME π¦
valkey-valkey-json β Valkey JSON
okay so real quick β this page is straight outta the Valkey Manual, section 7, and it's the whole glow-up story of JSON living inside your Valkey server π
β¨ DESCRIPTION β¨
bestie. In Valkey, the JSON data type and all its commands are implemented in the valkey-json module β and that's an official valkey module, no third-party chaos, and it's compatible with versions 8.0 and above. So yeah, users will need to load this module onto their valkey server in order to use this feature. No module loaded, no JSON. That's just the vibe. π
Valkey JSON is a Valkey module written in C++ that provides native JSON (JavaScript Object Notation) support for Valkey. And the implementation does not freestyle β it complies with RFC7159 and ECMA-404 JSON data interchange standards. Iconic, honestly. Users can natively store, query, and modify JSON data structures using the JSONPath query language. The query expressions support advanced capabilities including wildcard selections, filter expressions, array slices, union operations, and recursive searches. π it's giving powerful
π Example Valkey JSON Commands π
JSON.SETsets JSON values at the path.JSON.GETgets the serialized JSON at one or multiple paths.JSON.ARRINSERTinserts one or more values into the array values at path before the index.JSON.ARRLENgets the length of the array at the path.
See the valkey-commands(7) complete list of valkey-json commands. π
π Common use cases for Valkey JSON π
Prior to the valkey-json module, storing JSON in Valkey typically involved serializing it into a string or use hash datatype. And ngl? That approach made it difficult to work with nested data or perform partial updates. Lowkey a struggle era. π valkey-json addresses these limitations by enabling native JSON support.
Valkey JSON provides an efficient way to store and manipulate structured data. Its key benefits include fast search and filtering capabilities. It also provides the ability to perform in-place updates to JSON data without needing to overwrite entire documents. These features allow you to efficiently query, modify, and manage complex data structures, making it an ideal choice for applications that require dynamic and flexible data storage. main character data storage fr fr β¨
π§ JSON Properties π§
- Max Document Size β valkey-json allows configuring a limit on the size of individual JSON keys to prevent potential out-of-memory issues from malicious or unbounded insertions (e.g., via
JSON.ARRINSERT). By default, this value is0, meaning there is no limit. You can set this limit using theCONFIG SET json.max-document-size <value>command. UseJSON.DEBUG MEMORY <key>orMEMORY USAGE <key>to inspect memory usage. - Max Depth β The maximum nesting level for JSON objects and arrays. If a JSON object or array contains another object or array, it is considered nested. The default maximum allowed nesting depth is
128. Any attempt to exceed this limit will result in an error. You can adjust this limit using the following command:CONFIG SET json.max-path-limit <value>where value is the desired depth limit.
β‘ Performance β‘
The performance of JSON operations in Valkey is primarily influenced by the complexity of the JSONPath evaluation and the size or depth of the JSON object. Most operations β including JSON.GET, JSON.SET, JSON.DEL, JSON.NUMINCRBY, JSON.STRAPPEND and JSON.ARRAPPEND β are typically O(1) when using direct paths but may increase to a complexity of O(N), where N is the number of paths matched. Simpler paths like $.user.name perform significantly faster than recursive or filtered queries such as $..[?(@.active==true)].
For optimal performance, it's recommended to minimize excessive nesting, avoid frequent mutations of deeply nested objects, and use path filters judiciously.
π lowkey the moral of the story: don't nest your data like it's a 2019 group chat reply thread, bestie
π JSON ACL π
- Similar to the existing per-datatype categories (
@string,@hash, etc.), a new category@jsonis added to simplify managing access to JSON commands and data. No other existing Valkey commands are members of the@jsoncategory. All JSON commands enforce any keyspace or command restrictions and permissions. - There are 4 existing Valkey ACL categories which are updated to include new JSON commands:
@read,@write,@fast,@slow. The following table indicates the mapping of JSON commands to the appropriate categories.
For each of these categories and a row for each command, if the cell contains a "y" then that command is added into that category. π
JSON.ARRAPPENDβ@json,@write,@fastJSON.ARRINDEXβ@json,@read,@fastJSON.ARRINSERTβ@json,@write,@fastJSON.ARRLENβ@json,@read,@fastJSON.ARRPOPβ@json,@write,@fastJSON.ARRTRIMβ@json,@write,@fastJSON.CLEARβ@json,@write,@fastJSON.DEBUGβ@json,@read,@slowJSON.DELβ@json,@write,@fastJSON.FORGETβ@json,@write,@fastJSON.GETβ@json,@read,@fastJSON.MGETβ@json,@read,@fastJSON.MSETβ@json,@write,@fastJSON.NUMINCRBYβ@json,@write,@fastJSON.NUMMULTBYβ@json,@write,@fastJSON.OBJKEYSβ@json,@read,@fastJSON.OBJLENβ@json,@read,@fastJSON.RESPβ@json,@read,@fastJSON.SETβ@json,@write,@fastJSON.STRAPPENDβ@json,@write,@fastJSON.STRLENβ@json,@read,@fastJSON.TOGGLEβ@json,@write,@fastJSON.TYPEβ@json,@read,@fast
πΈ Path Syntax πΈ
Valkey JSON supports two kinds of path syntaxes:
- Enhanced syntax β Follows the JSONPath syntax described by Goessner, as shown in the following table. We've reordered and modified the descriptions in the table for clarity.
- Restricted syntax β Has limited query capabilities.
If a query path starts with $, it uses the enhanced syntax. Otherwise, the restricted syntax is used. It is recommended that you use the enhanced syntax for new development. π
β¨ Enhanced Syntax Symbols & Expressions β¨
$β The root element..or[]β Child operator...β Recursive descent.*β Wildcard. All elements in an object or array.[]β Array subscript operator. Index is0-based.[ , ]β Union operator.[start:end:step]β Array slice operator.?()β Applies a filter (script) expression to the current array or object.()β Filter expression.@β Used in filter expressions that refer to the current node being processed.==β Equal to, used in filter expressions.!=β Not equal to, used in filter expressions.>β Greater than, used in filter expressions.>=β Greater than or equal to, used in filter expressions.<β Less than, used in filter expressions.<=β Less than or equal to, used in filter expressions.&&β Logical AND, used to combine multiple filter expressions.||β Logical OR, used to combine multiple filter expressions.
π Examples π
The following examples are built on Goessner's example XML data, which we have modified by adding additional fields.
{ "store": {
"book": [
{ "category": "reference",
"author": "Nigel Rees",
"title": "Sayings of the Century",
"price": 8.95,
"in-stock": true,
"sold": true
},
{ "category": "fiction",
"author": "Evelyn Waugh",
"title": "Sword of Honour",
"price": 12.99,
"in-stock": false,
"sold": true
},
{ "category": "fiction",
"author": "Herman Melville",
"title": "Moby Dick",
"isbn": "0-553-21311-3",
"price": 8.99,
"in-stock": true,
"sold": false
},
{ "category": "fiction",
"author": "J. R. R. Tolkien",
"title": "The Lord of the Rings",
"isbn": "0-395-19395-8",
"price": 22.99,
"in-stock": false,
"sold": false
}
],
"bicycle": {
"color": "red",
"price": 19.95,
"in-stock": true,
"sold": false
}
}
}
'$.store.book[*].author'β the authors of all the books in the store π'$..author'β all authors. every single one, no matter where they're hiding.'$.store.*'β all members of the store'$["store"].*'β all members of the store (same energy, bracket flavour)'$.store..price'β the price of everything in the store πΈ'$..*'β all recursive members of the JSON structure (yes. everything. the whole tree.)'$..book[*]'β all books'$..book[0]'β the first book π₯'$..book[-1]'β the last book'$..book[0:2]'β the first two books'$..book[0,1]'β the first two books (same thing, different fit)'$..book[0:4]'β books from index 0 to 3 (the ending index is not inclusive, so index 4 did not get an invite π ββοΈ)'$..book[0:4:2]'β books at index 0 and 2'$..book[?(@.isbn)]'β all books with an ISBN number'$..book[?(@.price < 10)]'β all books cheaper than $10'$..book[?(@["price"] < 10)]'β all books cheaper than $10 (alternate syntax)'$..book[?(@.["price"] < 10)]'β all books cheaper than $10 (alternate syntax)'$..book[?(@.price >= 10 && @.price <= 100)]'β all books in the price range of $10 to $100, inclusive'$..book[?(@.sold == true || @.in-stock == false)]'β all books sold or out of stock'$.store.book[?(@.["category"] == "fiction")]'β all books in the fiction category'$.store.book[?(@.["category"] != "fiction")]'β the original table ships no description for this one, so bestie I am not inventing one π
Additional filter expression examples:
127.0.0.1:6379> JSON.SET k1 . '{"books": [{"price":5,"sold":true,"in-stock":true,"title":"foo"}, {"price":15,"sold":false,"title":"abc"}]}'
OK
127.0.0.1:6379> JSON.GET k1 $.books[?(@.price>1&&@.price<20&&@.in-stock)]
"[{\"price\":5,\"sold\":true,\"in-stock\":true,\"title\":\"foo\"}]"
127.0.0.1:6379> JSON.GET k1 '$.books[?(@.price>1 && @.price<20 && @.in-stock)]'
"[{\"price\":5,\"sold\":true,\"in-stock\":true,\"title\":\"foo\"}]"
127.0.0.1:6379> JSON.GET k1 '$.books[?((@.price>1 && @.price<20) && (@.sold==false))]'
"[{\"price\":15,\"sold\":false,\"title\":\"abc\"}]"
127.0.0.1:6379> JSON.GET k1 '$.books[?(@.title == "abc")]'
[{"price":15,"sold":false,"title":"abc"}]
127.0.0.1:6379> JSON.SET k2 . '[1,2,3,4,5]'
127.0.0.1:6379> JSON.GET k2 $.*.[?(@>2)]
"[3,4,5]"
127.0.0.1:6379> JSON.GET k2 '$.*.[?(@ > 2)]'
"[3,4,5]"
127.0.0.1:6379> JSON.SET k3 . '[true,false,true,false,null,1,2,3,4]'
OK
127.0.0.1:6379> JSON.GET k3 $.*.[?(@==true)]
"[true,true]"
127.0.0.1:6379> JSON.GET k3 '$.*.[?(@ == true)]'
"[true,true]"
127.0.0.1:6379> JSON.GET k3 $.*.[?(@>1)]
"[2,3,4]"
127.0.0.1:6379> JSON.GET k3 '$.*.[?(@ > 1)]'
"[2,3,4]"
πΈ Restricted Syntax Symbols and Expressions πΈ
.or[]β child operator[]β array subscript operator. the index is 0-based, bestie, so the first thing is0, not1, and that is just how it is π
And here's the little starter-pack of paths, all written out:
'.store.book[0].author'β the author of the first book'.store.book[-1].author'β the author of the last book'.address.city'β city name'["store"]["book"][0]["title"]'β the title of the first book'["store"]["book"][-1]["title"]'β the title of the last book
π¨ Common error prefixes π¨
okay so every single error message comes with a prefix, and knowing them is lowkey a superpower. here's the whole list:
ERRβ a general errorLIMITβ an error that happens when the size limit gets exceeded. for example, the document size limit or the nesting depth limit was exceeded πNONEXISTENTβ a key or path does not exist (it's giving "who? never heard of her")OUTOFBOUNDARIESβ array index out of boundsSYNTAXERRβ syntax errorWRONGTYPEβ wrong value type
π JSON-related metrics π
json_total_memory_bytesβ total memory allocated to JSON objectsjson_num_documentsβ total number of documents in Valkey
Wanna check the core metrics? run this, it's literally one line:
info json_core_metrics
and that's the whole page, bestie π«Ά this was VALKEY-VALKEY-JSON(7), from version 9.0.0, dated 2025-10-21. go forth and query something iconic πβ¨
π¦ 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