VALKEY-VALKEY-JSON(7)

πŸ“¦ version 9.0.6, in fedora 44

πŸ¦‹ 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.SET sets JSON values at the path.
  • JSON.GET gets the serialized JSON at one or multiple paths.
  • JSON.ARRINSERT inserts one or more values into the array values at path before the index.
  • JSON.ARRLEN gets 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 is 0, meaning there is no limit. You can set this limit using the CONFIG SET json.max-document-size <value> command. Use JSON.DEBUG MEMORY <key> or MEMORY 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 @json is added to simplify managing access to JSON commands and data. No other existing Valkey commands are members of the @json category. 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, @fast
  • JSON.ARRINDEX β€” @json, @read, @fast
  • JSON.ARRINSERT β€” @json, @write, @fast
  • JSON.ARRLEN β€” @json, @read, @fast
  • JSON.ARRPOP β€” @json, @write, @fast
  • JSON.ARRTRIM β€” @json, @write, @fast
  • JSON.CLEAR β€” @json, @write, @fast
  • JSON.DEBUG β€” @json, @read, @slow
  • JSON.DEL β€” @json, @write, @fast
  • JSON.FORGET β€” @json, @write, @fast
  • JSON.GET β€” @json, @read, @fast
  • JSON.MGET β€” @json, @read, @fast
  • JSON.MSET β€” @json, @write, @fast
  • JSON.NUMINCRBY β€” @json, @write, @fast
  • JSON.NUMMULTBY β€” @json, @write, @fast
  • JSON.OBJKEYS β€” @json, @read, @fast
  • JSON.OBJLEN β€” @json, @read, @fast
  • JSON.RESP β€” @json, @read, @fast
  • JSON.SET β€” @json, @write, @fast
  • JSON.STRAPPEND β€” @json, @write, @fast
  • JSON.STRLEN β€” @json, @read, @fast
  • JSON.TOGGLE β€” @json, @write, @fast
  • JSON.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 is 0-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 is 0, not 1, 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 error
  • LIMIT β€” 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 bounds
  • SYNTAXERR β€” syntax error
  • WRONGTYPE β€” wrong value type

  • json_total_memory_bytes β€” total memory allocated to JSON objects
  • json_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