JavaScript Object Notation (JSON) provides an efficient way for you to store and
manipulate structured data in Memorystore for Redis Cluster. Using JSON provides you with the
following benefits:

- Having fast search and filtering capabilities
- Performing in-place updates to JSON data without having to overwrite entire documents
- Querying, modifying, and managing complex data structures efficiently

If your applications require dynamic and flexible data storage, then JSON is
ideal choice for you. Also, by using JSON, you can encode complex datasets
inside of clusters in Memorystore for Redis Cluster without using schemas. You can
store, access, and update data in the clusters, and you don't have to manage
custom code to serialize and deserialize the data.

A *JSON document* is a human-readable text format for storing and transporting
data. This format consists of key-value pairs and structured data types. The
JSON format lets you retrieve and update portions of a JSON document without
having to manipulate the entire object. This can improve your performance and
reduce your costs. In addition, the JSON format is compliant with [RFC 7159](https://www.ietf.org/rfc/rfc7159.txt), the [ECMA-404](https://ecma-international.org/publications-and-standards/standards/ecma-404/)
JSON data interchange standard, and UTF-8 [Unicode](https://www.unicode.org/standard/WhatIsUnicode.html)
in JSON text.

## Availability

If you create a cluster in Memorystore for Redis Cluster, version 8.0 and later, then
version 1.0 of the [JSON data type and associated commands](https://github.com/valkey-io/valkey-json)
is available automatically. This data type is API-compatible with version 2 of
the JSON module. Also, as of RFC 7159, the root element of a JSON document can
be of any JSON data type.

## JSON properties

JSON has the following properties:

- **Max document size**: to prevent potential out-of-memory issues from
  malicious or unbounded insertions, you can configure a limit on the size of
  individual JSON keys.

  By default, the value for this property is set to `0`, which means that
  there's no limit to the size of the JSON document. To set this limit, use the
  [`CONFIG SET json.max-document-size VALUE`](https://valkey.io/commands/config-set/)
  command, where <var translate="no">VALUE</var> is the maximum size of the document. For example, if
  you specify `4123456`, then the maximum document size is 4,123,456 bytes
  (4 MB).

  To see how much memory is used by a JSON value that's stored in a specified
  key, you can use the [`JSON.DEBUG MEMORY KEY`](https://valkey.io/commands/json.debug/) or [`MEMORY USAGE KEY`](https://valkey.io/commands/memory-usage/)
  commands. For these commands, <var translate="no">KEY</var> is the name of the key where the
  JSON value is stored.
- **Max depth** : the maximum nesting level for JSON objects and arrays. For more
  information, see [Maximum nesting depth limit](https://docs.cloud.google.com/memorystore/docs/cluster/about-json.md.txt#maximum-nesting-depth-limit).

## JSON document size

Because a JSON document is stored internally in a format that's optimized for
rapid access and modification, this type of document can consume a lot of
memory. To check how much memory a JSON document consumes, use the
[`JSON.DEBUG MEMORY KEY`](https://valkey.io/commands/json.debug/)
command, where <var translate="no">KEY</var> is the name of the key that contains the document.

## JSON categories

To manage access to [JSON commands](https://docs.cloud.google.com/memorystore/docs/cluster/about-json.md.txt#json-commands) and data, use the `@json`
category. In addition to this category, the following categories use JSON
commands: `@read`, `@write`, `@fast`, `@slow`, and `@admin`.

The following table indicates whether you can map JSON commands to the `@read`,
`@write`, `@fast`, `@slow`, `@admin`, and `@json` categories.

| JSON command | `@json` | `@read` | `@write` | `@fast` | `@slow` | `@admin` |
|---|---|---|---|---|---|---|
| `JSON.ARRAPPEND` | Y | N | Y | Y | N | N |
| `JSON.ARRINDEX` | Y | Y | N | Y | N | N |
| `JSON.ARRINSERT` | Y | N | Y | Y | N | N |
| `JSON.ARRLEN` | Y | Y | N | Y | N | N |
| `JSON.ARRPOP` | Y | N | Y | Y | N | N |
| `JSON.ARRTRIM` | Y | N | Y | Y | N | N |
| `JSON.CLEAR` | Y | N | Y | Y | N | N |
| `JSON.DEBUG` | Y | Y | N | N | Y | Y |
| `JSON.DEL` | Y | N | Y | Y | N | N |
| `JSON.FORGET` | Y | N | Y | Y | N | N |
| `JSON.GET` | Y | Y | N | Y | N | N |
| `JSON.MGET` | Y | Y | N | Y | N | N |
| `JSON.MSET` | Y | N | Y | N | Y | N |
| `JSON.NUMINCRBY` | Y | N | Y | Y | N | N |
| `JSON.NUMMULTBY` | Y | N | Y | Y | N | N |
| `JSON.OBJKEYS` | Y | Y | N | Y | N | N |
| `JSON.OBJLEN` | Y | Y | N | Y | N | N |
| `JSON.RESP` | Y | Y | N | Y | N | N |
| `JSON.SET` | Y | N | Y | N | Y | N |
| `JSON.STRAPPEND` | Y | N | Y | Y | N | N |
| `JSON.STRLEN` | Y | Y | N | Y | N | N |
| `JSON.TOGGLE` | Y | N | Y | Y | N | N |
| `JSON.TYPE` | Y | Y | N | Y | N | N |

## JSON metrics

To monitor the usage of JSON documents, the following Cloud Monitoring
metrics are available in Memorystore for Redis Cluster:

- `documents_count`
- `used_memory`

For more information about these metrics, see [JSON metrics](https://docs.cloud.google.com/memorystore/docs/cluster/supported-monitoring-metrics.md.txt#json-metrics).

## JSON commands

This section lists and describes the JSON commands that you can use to perform
operations on JSON documents.

| Command | Description |
|---|---|
| `JSON.ARRAPPEND` | Append one or more JSON values into the array at the path. |
| `JSON.ARRINDEX` | Search for the first occurrence of a scalar JSON value in an array. |
| `JSON.ARRINSERT` | Insert one or more JSON values into an array at a path before the index that you specify. |
| `JSON.ARRLEN` | Retrieve the length of the JSON array at the path. |
| `JSON.ARRPOP` | Remove and return an element from an index in the array. |
| `JSON.ARRTRIM` | Trim an array at the path so that it contains only the inclusive range of elements that you specify. |
| `JSON.CLEAR` | Clear the arrays or a JSON object at a path that you specify. |
| `JSON.DEBUG` | Retrieve information about a JSON document. Memorystore for Redis Cluster supports the following subcommands: - `MEMORY`: report a value's memory usage in bytes. <!-- --> - `DEPTH`: report the maximum path depth of a JSON document. <!-- --> - `FIELDS`: report the number of fields within a JSON element. This element is stored at a key that you specify. <!-- --> - `HELP`: return helpful information about the `JSON.DEBUG` command. |
| `JSON.DEL` `JSON.FORGET` | Delete JSON values at a path that you specify. |
| `JSON.GET` | Return a value at a path that you specify in JSON serialized form. |
| `JSON.MGET` | Return values at a path that you specify from multiple document keys. |
| `JSON.MSET` | Set multiple JSON values at a path to multiple keys. |
| `JSON.NUMINCRBY` | Increment numeric values that are stored at a path by a number that you specify. |
| `JSON.NUMMULTBY` | Multiply numeric values that are stored at a path by a number that you specify. |
| `JSON.OBJKEYS` | Retrieve key names from JSON objects at a path that you specify. |
| `JSON.OBJLEN` | Retrieve the number of keys in a JSON object at a path that you specify. |
| `JSON.RESP` | Return the JSON value of a key in the [Redis serialization protocol (RESP)](https://redis.io/docs/latest/develop/reference/protocol-spec/) form. |
| `JSON.SET` | Set JSON values at a path that you specify. |
| `JSON.STRAPPEND` | Append a string to JSON strings at a path that you specify. |
| `JSON.STRLEN` | Retrieve the length of JSON string values at a path that you specify. |
| `JSON.TOGGLE` | Toggle a boolean value between `true` and `false`. This value is stored at a path that you specify. |
| `JSON.TYPE` | Retrieve the type of a JSON value at a path that you specify. |

> [!NOTE]
> **Note** : For more information about using these
> commands, see the [Valkey command
> reference](https://valkey.io/commands/#json) page. You can check the performance of using these
> commands. For more information, see [Performance](https://valkey.io/topics/valkey-json/#performance).

## How Memorystore for Redis Cluster interacts with JSON

This section describes how Memorystore for Redis Cluster interacts with the JSON data
type.

### Multiple conditional expressions

If there are multiple conditional expressions for filtering, then
Memorystore for Redis Cluster evaluates them in the following order:

1. Operations inside of parentheses
2. The logical `AND` expression (`&&`)
3. The logical `OR` (`||`) expression

### Maximum nesting depth limit

When a JSON object or array has an element that's another JSON object or array,
the inner object or array nests within the outer object or array. The maximum
nesting depth limit is 128. So, a value like `$.a.b.c.d...` can reach only 128
levels.

If you attempt to create a JSON document that contains a nesting depth greater
than 128, then Memorystore for Redis Cluster rejects the document and you receive an
error. However, you can adjust this limit by using the [`CONFIG SET json.max-path-limit VALUE`](https://valkey.io/commands/config-set/) command, where
<var translate="no">VALUE</var> is the depth limit that you want.

### JSON numbers

In JSON, both floating point numbers and integers are called numbers because
they have the same data type. When Memorystore for Redis Cluster receives a JSON
number, it converts the number into one of the following internal binary
representations:

- A 64-bit IEEE double precision floating point number
- A 64-bit signed integer

JSON doesn't retain the original string and all of its formatting. When
Memorystore for Redis Cluster outputs a number as part of a JSON response,
Memorystore for Redis Cluster converts the number from the internal binary
representation to a printable string that uses generic formatting rules.

When you use the [`JSON.NUMINCRBY`](https://docs.cloud.google.com/memorystore/docs/cluster/about-json.md.txt#json-commands) and [`JSON.NUMMULTBY`](https://docs.cloud.google.com/memorystore/docs/cluster/about-json.md.txt#json-commands)
commands with JSON numbers, the following conditions apply:

- If both numbers are integers and the result is out of the range of `int64`, then the result becomes a 64-bit IEEE double precision floating point number automatically.
- If at least one of the numbers is a floating point number, then the result is a 64-bit IEEE double precision floating point number.
- If the result exceeds the range of the 64-bit IEEE double precision floating point number, then you receive an `OVERFLOW` error message.

### Direct arrays

Memorystore for Redis Cluster filters array objects directly. For example, if you have
data such as  
\[`0`,`1`,`2`,`3`\] and a path query such as
`$[?(@<3)]`, then Memorystore for Redis Cluster returns
\[`0,1,2`\]. For data such as {`"my_valkey_key":[0,1,2,3]`}
and a path query such as  
`$.my_valkey_key[?(@<3)]`,
Memorystore for Redis Cluster also returns \[`0,1,2`\].

### Array indexes

Memorystore for Redis Cluster lets you use positive and negative indexes for arrays.
The following conditions apply to these types of indexes:

- **Positive index** : numbers start at the *beginning* of the array. For example, if an array has a positive index of three, then 0 queries the first element, 1 queries the second element, and 2 queries the third element.
- **Negative index** : numbers start at the *end* of the array. If an array has a negative index of three, then -1 queries the third element, -2 queries the second element, and -3 queries the first element.

Memorystore for Redis Cluster doesn't round indexes up or down. If you have an array
with a length of 3, and you call either a positive index that's greater than 3
or a negative index that's less than -3, then Memorystore for Redis Cluster doesn't
return a result.

### Syntax for JSON paths

You can't use invalid syntax for your JSON paths. This condition applies, even
if a subset of a JSON path with an invalid syntax contains a valid path.