title: INFO

summary: Returns information and statistics about the server.

title: Notes

text:
Please note depending on the version of Redis some of the fields have been
added or removed. A robust client application should therefore parse the
result of this command by skipping unknown properties, and gracefully handle
missing fields.

Here is the description of fields for Redis >= 2.4.

Here is the meaning of all fields in the **server** section:

*   `redis_version`: Version of the Redis server
*   `redis_git_sha1`:  Git SHA1
*   `redis_git_dirty`: Git dirty flag
*   `redis_build_id`: The build id
*   `redis_mode`: The server's mode ("standalone", "sentinel" or "cluster")
*   `os`: Operating system hosting the Redis server
*   `arch_bits`: Architecture (32 or 64 bits)
*   `multiplexing_api`: Event loop mechanism used by Redis
*   `atomicvar_api`: Atomicvar API used by Redis
*   `gcc_version`: Version of the GCC compiler used to compile the Redis server
*   `process_id`: PID of the server process
*   `process_supervised`: Supervised system ("upstart", "systemd", "unknown" or "no")
*   `run_id`: Random value identifying the Redis server (to be used by Sentinel
     and Cluster)
*   `tcp_port`: TCP/IP listen port
*   `server_time_usec`: Epoch-based system time with microsecond precision
*   `uptime_in_seconds`: Number of seconds since Redis server start
*   `uptime_in_days`: Same value expressed in days
*   `hz`: The server's current frequency setting
*   `configured_hz`: The server's configured frequency setting
*   `lru_clock`: Clock incrementing every minute, for LRU management
*   `executable`: The path to the server's executable
*   `config_file`: The path to the config file
*   `io_threads_active`: Flag indicating if I/O threads are active
*   `shutdown_in_milliseconds`: The maximum time remaining for replicas to catch up the replication before completing the shutdown sequence.
    This field is only present during shutdown.

Here is the meaning of all fields in the **clients** section:

*   `connected_clients`: Number of client connections (excluding connections
     from replicas)
*   `cluster_connections`: An approximation of the number of sockets used by the
     cluster's bus
*   `maxclients`: The value of the `maxclients` configuration directive. This is
    the upper limit for the sum of `connected_clients`, `connected_slaves` and
    `cluster_connections`.
*   `client_recent_max_input_buffer`: Biggest input buffer among current client connections
*   `client_recent_max_output_buffer`: Biggest output buffer among current client connections
*   `blocked_clients`: Number of clients pending on a blocking call ([`BLPOP`](),
     [`BRPOP`](), [`BRPOPLPUSH`](), [`BLMOVE`](), [`BZPOPMIN`](), [`BZPOPMAX`]())
*   `tracking_clients`: Number of clients being tracked ([`CLIENT TRACKING`]())
*   `pubsub_clients`: Number of clients in pubsub mode ([`SUBSCRIBE`](), [`PSUBSCRIBE`](), [`SSUBSCRIBE`]()). Added in Redis 7.4
*   `watching_clients`: Number of clients in watching mode ([`WATCH`]()). Added in Redis 7.4
*   `clients_in_timeout_table`: Number of clients in the clients timeout table
*   `total_watched_keys`: Number of watched keys. Added in Redis 7.4.
*   `total_blocking_keys`: Number of blocking keys. Added in Redis 7.2.
*   `total_blocking_keys_on_nokey`: Number of blocking keys that one or more clients that would like to be unblocked when the key is deleted. Added in Redis 7.2.

Here is the meaning of all fields in the **memory** section:

*   `used_memory`: Total number of bytes allocated by Redis using its
     allocator (either standard **libc**, **jemalloc**, or an alternative
     allocator such as [**tcmalloc**][hcgcpgp])
*   `used_memory_human`: Human readable representation of previous value
*   `used_memory_rss`: Number of bytes that Redis allocated as seen by the
     operating system (a.k.a resident set size). This is the number reported by
     tools such as `top(1)` and `ps(1)`
*   `used_memory_rss_human`: Human readable representation of previous value
*   `used_memory_peak`: Peak memory consumed by Redis (in bytes)
*   `used_memory_peak_human`: Human readable representation of previous value
*   `used_memory_peak_time`: Time when peak memory was recorded
*   `used_memory_peak_perc`: The percentage of `used_memory` out of `used_memory_peak`
*   `used_memory_overhead`: The sum in bytes of all overheads that the server
     allocated for managing its internal data structures
*   `used_memory_startup`: Initial amount of memory consumed by Redis at startup
     in bytes
*   `used_memory_dataset`: The size in bytes of the dataset
     (`used_memory_overhead` subtracted from `used_memory`)
*   `used_memory_dataset_perc`: The percentage of `used_memory_dataset` out of
     the net memory usage (`used_memory` minus `used_memory_startup`)
*   `total_system_memory`: The total amount of memory that the Redis host has
*   `total_system_memory_human`: Human readable representation of previous value
*   `used_memory_lua`: Number of bytes used by the Lua engine for EVAL scripts. Deprecated in Redis 7.0, renamed to `used_memory_vm_eval`
*   `used_memory_vm_eval`: Number of bytes used by the script VM engines for EVAL framework (not part of used_memory). Added in Redis 7.0
*   `used_memory_lua_human`: Human readable representation of previous value. Deprecated in Redis 7.0
*   `used_memory_scripts_eval`: Number of bytes overhead by the EVAL scripts (part of used_memory). Added in Redis 7.0
*   `number_of_cached_scripts`: The number of EVAL scripts cached by the server. Added in Redis 7.0
*   `number_of_functions`: The number of functions. Added in Redis 7.0
*   `number_of_libraries`: The number of libraries. Added in Redis 7.0
*   `used_memory_vm_functions`: Number of bytes used by the script VM engines for Functions framework (not part of used_memory). Added in Redis 7.0
*   `used_memory_vm_total`: `used_memory_vm_eval` + `used_memory_vm_functions` (not part of used_memory). Added in Redis 7.0
*   `used_memory_vm_total_human`: Human readable representation of previous value.
*   `used_memory_functions`: Number of bytes overhead by Function scripts (part of used_memory). Added in Redis 7.0
*   `used_memory_scripts`: `used_memory_scripts_eval` + `used_memory_functions` (part of used_memory). Added in Redis 7.0
*   `used_memory_scripts_human`: Human readable representation of previous value
*   `maxmemory`: The value of the `maxmemory` configuration directive
*   `maxmemory_human`: Human readable representation of previous value
*   `maxmemory_policy`: The value of the `maxmemory-policy` configuration
     directive
*   `mem_fragmentation_ratio`: Ratio between `used_memory_rss` and `used_memory`.
    Note that this doesn't only includes fragmentation, but also other process overheads (see the `allocator_*` metrics), and also overheads like code, shared libraries, stack, etc.
*   `mem_fragmentation_bytes`: Delta between `used_memory_rss` and `used_memory`.
    Note that when the total fragmentation bytes is low (few megabytes), a high ratio (e.g. 1.5 and above) is not an indication of an issue.
*   `allocator_frag_ratio:`: Ratio between `allocator_active` and `allocator_allocated`. This is the true (external) fragmentation metric (not `mem_fragmentation_ratio`).
*   `allocator_frag_bytes` Delta between `allocator_active` and `allocator_allocated`. See note about `mem_fragmentation_bytes`.
*   `allocator_rss_ratio`: Ratio between `allocator_resident` and `allocator_active`. This usually indicates pages that the allocator can and probably will soon release back to the OS.
*   `allocator_rss_bytes`: Delta between `allocator_resident` and `allocator_active`
*   `rss_overhead_ratio`: Ratio between `used_memory_rss` (the process RSS) and `allocator_resident`. This includes RSS overheads that are not allocator or heap related.
*   `rss_overhead_bytes`: Delta between `used_memory_rss` (the process RSS) and `allocator_resident`
*   `allocator_allocated`: Total bytes allocated form the allocator, including internal-fragmentation. Normally the same as `used_memory`.
*   `allocator_active`: Total bytes in the allocator active pages, this includes external-fragmentation.
*   `allocator_resident`: Total bytes resident (RSS) in the allocator, this includes pages that can be released to the OS (by [`MEMORY PURGE`](), or just waiting).
*   `allocator_muzzy`: Total bytes of 'muzzy' memory (RSS) in the allocator. Muzzy memory is memory that has been freed, but not yet fully returned to the operating system. It can be reused immediately when needed or reclaimed by the OS when system pressure increases.
*   `mem_not_counted_for_evict`: Used memory that's not counted for key eviction. This is basically transient replica and AOF buffers.
*   `mem_clients_slaves`: Memory used by replica clients - Starting Redis 7.0, replica buffers share memory with the replication backlog, so this field can show 0 when replicas don't trigger an increase of memory usage.
*   `mem_clients_normal`: Memory used by normal clients
*   `mem_cluster_links`: Memory used by links to peers on the cluster bus when cluster mode is enabled.
*   `mem_cluster_slot_migration_output_buffer`: Memory usage of the migration client's output buffer. Redis writes incoming changes to this buffer during the migration process.
*   `mem_cluster_slot_migration_input_buffer`: Memory usage of the accumulated replication stream buffer on the importing node.
*   `mem_cluster_slot_migration_input_buffer_peak`: Peak accumulated repl buffer size on the importing side.
*   `mem_aof_buffer`: Transient memory used for AOF and AOF rewrite buffers
*   `mem_replication_backlog`: Memory used by replication backlog
*   `mem_total_replication_buffers`: Total memory consumed for replication buffers - Added in Redis 7.0.
*   `mem_allocator`: Memory allocator, chosen at compile time.
*   `mem_overhead_db_hashtable_rehashing`: Temporary memory overhead of database dictionaries currently being rehashed - Added in 7.4.
*   `active_defrag_running`: When `activedefrag` is enabled, this indicates whether defragmentation is currently active, and the CPU percentage it intends to utilize.
*   `lazyfree_pending_objects`: The number of objects waiting to be freed (as a
     result of calling [`UNLINK`](), or [`FLUSHDB`]() and [`FLUSHALL`]() with the **ASYNC**
     option)
*   `lazyfreed_objects`: The number of objects that have been lazy freed.

Ideally, the `used_memory_rss` value should be only slightly higher than
`used_memory`.
When rss >> used, a large difference may mean there is (external) memory fragmentation, which can be evaluated by checking
`allocator_frag_ratio`, `allocator_frag_bytes`.
When used >> rss, it means part of Redis memory has been swapped off by the
operating system: expect some significant latencies.

Because Redis does not have control over how its allocations are mapped to
memory pages, high `used_memory_rss` is often the result of a spike in memory
usage.

When Redis frees memory, the memory is given back to the allocator, and the
allocator may or may not give the memory back to the system. There may be
a discrepancy between the `used_memory` value and memory consumption as
reported by the operating system. It may be due to the fact memory has been
used and released by Redis, but not given back to the system. The
`used_memory_peak` value is generally useful to check this point.

Additional introspective information about the server's memory can be obtained
by referring to the [`MEMORY STATS`]() command and the [`MEMORY DOCTOR`]().

Here is the meaning of all fields in the **persistence** section:

*   `loading`: Flag indicating if the load of a dump file is on-going
*   `async_loading`: Currently loading replication data-set asynchronously while serving old data. This means `repl-diskless-load` is enabled and set to `swapdb`. Added in Redis 7.0.
*   `current_cow_peak`: The peak size in bytes of copy-on-write memory
     while a child fork is running
*   `current_cow_size`: The size in bytes of copy-on-write memory
     while a child fork is running
*   `current_cow_size_age`: The age, in seconds, of the `current_cow_size` value.
*   `current_fork_perc`: The percentage of progress of the current fork process. For AOF and RDB forks it is the percentage of `current_save_keys_processed` out of `current_save_keys_total`.
*   `current_save_keys_processed`: Number of keys processed by the current save operation
*   `current_save_keys_total`: Number of keys at the beginning of the current save operation
*   `rdb_changes_since_last_save`: Number of changes since the last dump
*   `rdb_bgsave_in_progress`: Flag indicating a RDB save is on-going
*   `rdb_last_save_time`: Epoch-based timestamp of last successful RDB save
*   `rdb_last_bgsave_status`: Status of the last RDB save operation
*   `rdb_last_bgsave_time_sec`: Duration of the last RDB save operation in
     seconds
*   `rdb_current_bgsave_time_sec`: Duration of the on-going RDB save operation
     if any
*   `rdb_last_cow_size`: The size in bytes of copy-on-write memory during
     the last RDB save operation
*   `rdb_last_load_keys_expired`: Number of volatile keys deleted during the last RDB loading. Added in Redis 7.0.
*   `rdb_last_load_keys_loaded`: Number of keys loaded during the last RDB loading. Added in Redis 7.0.
*   `aof_enabled`: Flag indicating AOF logging is activated
*   `aof_rewrite_in_progress`: Flag indicating a AOF rewrite operation is
     on-going
*   `aof_rewrite_scheduled`: Flag indicating an AOF rewrite operation
     will be scheduled once the on-going RDB save is complete.
*   `aof_last_rewrite_time_sec`: Duration of the last AOF rewrite operation in
     seconds
*   `aof_current_rewrite_time_sec`: Duration of the on-going AOF rewrite
     operation if any
*   `aof_last_bgrewrite_status`: Status of the last AOF rewrite operation
*   `aof_last_write_status`: Status of the last write operation to the AOF
*   `aof_last_cow_size`: The size in bytes of copy-on-write memory during
     the last AOF rewrite operation
*   `module_fork_in_progress`: Flag indicating a module fork is on-going
*   `module_fork_last_cow_size`: The size in bytes of copy-on-write memory
     during the last module fork operation
*   `aof_rewrites`: Number of AOF rewrites performed since startup
*   `rdb_saves`: Number of RDB snapshots performed since startup

`rdb_changes_since_last_save` refers to the number of operations that produced
some kind of changes in the dataset since the last time either [`SAVE`]() or
[`BGSAVE`]() was called.

If AOF is activated, these additional fields will be added:

*   `aof_current_size`: AOF current file size
*   `aof_base_size`: AOF file size on latest startup or rewrite
*   `aof_pending_rewrite`: Flag indicating an AOF rewrite operation
     will be scheduled once the on-going RDB save is complete.
*   `aof_buffer_length`: Size of the AOF buffer
*   `aof_rewrite_buffer_length`: Size of the AOF rewrite buffer. Note this field was removed in Redis 7.0
*   `aof_pending_bio_fsync`: Number of fsync pending jobs in background I/O
     queue
*   `aof_delayed_fsync`: Delayed fsync counter

If a load operation is on-going, these additional fields will be added:

*   `loading_start_time`: Epoch-based timestamp of the start of the load
     operation
*   `loading_total_bytes`: Total file size
*   `loading_rdb_used_mem`: The memory usage of the server that had generated
    the RDB file at the time of the file's creation
*   `loading_loaded_bytes`: Number of bytes already loaded
*   `loading_loaded_perc`: Same value expressed as a percentage
*   `loading_eta_seconds`: ETA in seconds for the load to be complete

The **threads** section provides statistics on I/O threads.
 The statistics are the number of assigned clients,
 the number of read events processed, and the number of write events processed.
 Added in Redis 8.0.

For each I/O thread, the following line is added:

*   `io_thread_XXX`: `clients=XXX,reads=XXX,writes=XXX`

Here is the meaning of all fields in the **stats** section:

*   `total_connections_received`: Total number of connections accepted by the
     server
*   `total_commands_processed`: Total number of commands processed by the server
*   `instantaneous_ops_per_sec`: Number of commands processed per second
*   `total_net_input_bytes`: The total number of bytes read from the network
*   `total_net_output_bytes`: The total number of bytes written to the network
*   `total_net_repl_input_bytes`: The total number of bytes read from the network for replication purposes
*   `total_net_repl_output_bytes`: The total number of bytes written to the network for replication purposes
*   `instantaneous_input_kbps`: The network's read rate per second in KB/sec
*   `instantaneous_output_kbps`: The network's write rate per second in KB/sec
*   `instantaneous_input_repl_kbps`: The network's read rate per second in KB/sec for replication purposes
*   `instantaneous_output_repl_kbps`: The network's write rate per second in KB/sec for replication purposes
*   `rejected_connections`: Number of connections rejected because of
     `maxclients` limit
*   `sync_full`: The number of full resyncs with replicas
*   `sync_partial_ok`: The number of accepted partial resync requests
*   `sync_partial_err`: The number of denied partial resync requests
*   `expired_subkeys`: The number of hash field expiration events
*   `expired_keys`: Total number of key expiration events
*   `expired_stale_perc`: The percentage of keys probably expired
*   `expired_time_cap_reached_count`: The count of times that active expiry cycles have stopped early
*   `expire_cycle_cpu_milliseconds`: The cumulative amount of time spent on active expiry cycles
*   `evicted_keys`: Number of evicted keys due to `maxmemory` limit
*   `evicted_clients`: Number of evicted clients due to `maxmemory-clients` limit. Added in Redis 7.0.
*   `evicted_scripts`: Number of evicted EVAL scripts due to LRU policy, see [`EVAL`]() for more details. Added in Redis 7.4.
*   `total_eviction_exceeded_time`:  Total time `used_memory` was greater than `maxmemory` since server startup, in milliseconds
*   `current_eviction_exceeded_time`: The time passed since `used_memory` last rose above `maxmemory`, in milliseconds
*   `keyspace_hits`: Number of successful lookup of keys in the main dictionary
*   `keyspace_misses`: Number of failed lookup of keys in the main dictionary
*   `pubsub_channels`: Global number of pub/sub channels with client
     subscriptions
*   `pubsub_patterns`: Global number of pub/sub pattern with client
     subscriptions
*   `pubsubshard_channels`: Global number of pub/sub shard channels with client subscriptions. Added in Redis 7.0.3
*   `latest_fork_usec`: Duration of the latest fork operation in microseconds
*   `total_forks`: Total number of fork operations since the server start
*   `migrate_cached_sockets`: The number of sockets open for [`MIGRATE`]() purposes
*   `slave_expires_tracked_keys`: The number of keys tracked for expiry purposes
     (applicable only to writable replicas)
*   `active_defrag_hits`: Number of value reallocations performed by active the
     defragmentation process
*   `active_defrag_misses`: Number of aborted value reallocations started by the
     active defragmentation process
*   `active_defrag_key_hits`: Number of keys that were actively defragmented
*   `active_defrag_key_misses`: Number of keys that were skipped by the active
     defragmentation process
*   `total_active_defrag_time`: Total time memory fragmentation was over the limit, in milliseconds
*   `current_active_defrag_time`: The time passed since memory fragmentation last was over the limit, in milliseconds
*   `tracking_total_keys`: Number of keys being tracked by the server
*   `tracking_total_items`: Number of items, that is the sum of clients number for
     each key, that are being tracked
*   `tracking_total_prefixes`: Number of tracked prefixes in server's prefix table
    (only applicable for broadcast mode)
*   `unexpected_error_replies`: Number of unexpected error replies, that are types
    of errors from an AOF load or replication
*   `total_error_replies`: Total number of issued error replies, that is the sum of
    rejected commands (errors prior command execution) and
    failed commands (errors within the command execution)
*   `dump_payload_sanitizations`: Total number of dump payload deep integrity validations (see `sanitize-dump-payload` config).
*   `total_reads_processed`: Total number of read events processed
*   `total_writes_processed`: Total number of write events processed
*   `io_threaded_reads_processed`: Number of read events processed by I/O threads
*   `io_threaded_writes_processed`: Number of write events processed by I/O threads
*   `client_query_buffer_limit_disconnections`: Total number of disconnections due to client reaching query buffer limit
*   `client_output_buffer_limit_disconnections`: Total number of disconnections due to client reaching output buffer limit
*   `reply_buffer_shrinks`: Total number of output buffer shrinks
*   `reply_buffer_expands`: Total number of output buffer expands
*   `eventloop_cycles`: Total number of eventloop cycles
*   `eventloop_duration_sum`: Total time spent in the eventloop in microseconds (including I/O and command processing)
*   `eventloop_duration_cmd_sum`: Total time spent on executing commands in microseconds
*   `instantaneous_eventloop_cycles_per_sec`: Number of eventloop cycles per second
*   `instantaneous_eventloop_duration_usec`: Average time spent in a single eventloop cycle in microseconds
*   `acl_access_denied_auth`: Number of authentication failures
*   `acl_access_denied_cmd`: Number of commands rejected because of access denied to the command
*   `acl_access_denied_key`: Number of commands rejected because of access denied to a key
*   `acl_access_denied_channel`: Number of commands rejected because of access denied to a channel
*   `acl_access_denied_tls_cert`: Number of failed TLS certificate–based authentication attempts
*   `cluster_incompatible_ops`: Number of cluster-incompatible commands. This metric appears only if the `cluster-compatibility-sample-ratio` configuration parameter is not 0. Added in Redis 8.0.

Here is the meaning of all fields in the **replication** section:

*   `role`: Value is "master" if the instance is replica of no one, or "slave" if the instance is a replica of some master instance.
     Note that a replica can be master of another replica (chained replication).
*   `master_failover_state`: The state of an ongoing failover, if any.
*   `master_replid`: The replication ID of the Redis server.
*   `master_replid2`: The secondary replication ID, used for PSYNC after a failover.
*   `master_repl_offset`: The server's current replication offset
*   `second_repl_offset`: The offset up to which replication IDs are accepted
*   `repl_backlog_active`: Flag indicating replication backlog is active
*   `repl_backlog_size`: Total size in bytes of the replication backlog buffer
*   `repl_backlog_first_byte_offset`: The master offset of the replication
     backlog buffer
*   `repl_backlog_histlen`: Size in bytes of the data in the replication backlog
     buffer

If the instance is a replica, these additional fields are provided:

*   `master_host`: Host or IP address of the master
*   `master_port`: Master listening TCP port
*   `master_link_status`: Status of the link (up/down)
*   `master_last_io_seconds_ago`: Number of seconds since the last interaction
     with master
*   `master_sync_in_progress`: Indicate the master is syncing to the replica
*   `slave_read_repl_offset`: The read replication offset of the replica instance.
*   `slave_repl_offset`: The replication offset of the replica instance
*   `slave_priority`: The priority of the instance as a candidate for failover
*   `slave_read_only`: Flag indicating if the replica is read-only
*   `replica_announced`: Flag indicating if the replica is announced by Sentinel.

If a SYNC operation is on-going, these additional fields are provided:

*   `master_sync_total_bytes`: Total number of bytes that need to be
    transferred. this may be 0 when the size is unknown (for example, when
    the `repl-diskless-sync` configuration directive is used)
*   `master_sync_read_bytes`: Number of bytes already transferred
*   `master_sync_left_bytes`: Number of bytes left before syncing is complete
    (may be negative when `master_sync_total_bytes` is 0)
*   `master_sync_perc`: The percentage `master_sync_read_bytes` from
    `master_sync_total_bytes`, or an approximation that uses
    `loading_rdb_used_mem` when `master_sync_total_bytes` is 0
*   `master_sync_last_io_seconds_ago`: Number of seconds since last transfer I/O
     during a SYNC operation

If the link between master and replica is down, an additional field is provided:

*   `master_link_down_since_seconds`: Number of seconds since the link is down

The following field is always provided:

*   `connected_slaves`: Number of connected replicas

If the server is configured with the `min-slaves-to-write` (or starting with Redis 5 with the `min-replicas-to-write`) directive, an additional field is provided:

*   `min_slaves_good_slaves`: Number of replicas currently considered good

For each replica, the following line is added:

*   `slaveXXX`: id, IP address, port, state, offset, lag

Here is the meaning of all fields in the **cpu** section:

*   `used_cpu_sys`: System CPU consumed by the Redis server, which is the sum of system CPU consumed by all threads of the server process (main thread and background threads)
*   `used_cpu_user`: User CPU consumed by the Redis server, which is the sum of user CPU consumed by all threads of the server process (main thread and background threads)
*   `used_cpu_sys_children`: System CPU consumed by the background processes
*   `used_cpu_user_children`: User CPU consumed by the background processes
*   `used_cpu_sys_main_thread`: System CPU consumed by the Redis server main thread
*   `used_cpu_user_main_thread`: User CPU consumed by the Redis server main thread

The **commandstats** section provides statistics based on the command type,
 including the number of calls that reached command execution (not rejected),
 the total CPU time consumed by these commands, the average CPU consumed
 per command execution, the number of rejected calls
 (errors prior command execution), and the number of failed calls
 (errors within the command execution).

For each command type, the following line is added:

*   `cmdstat_XXX`: `calls=XXX,usec=XXX,usec_per_call=XXX,rejected_calls=XXX,failed_calls=XXX`

The **latencystats** section provides latency percentile distribution statistics based on the command type.

 By default, the exported latency percentiles are the p50, p99, and p999.
 If you need to change the exported percentiles, use `CONFIG SET latency-tracking-info-percentiles "50.0 99.0 99.9"`.

 This section requires the extended latency monitoring feature to be enabled (by default it's enabled).
 If you need to enable it, use `CONFIG SET latency-tracking yes`.

For each command type, the following line is added:

*   `latency_percentiles_usec_XXX: p<percentile 1>=<percentile 1 value>,p<percentile 2>=<percentile 2 value>,...`

The **errorstats** section enables keeping track of the different errors that occurred within Redis,
 based upon the reply error prefix ( The first word after the "-", up to the first space. Example: `ERR` ).

For each error type, the following line is added:

*   `errorstat_XXX`: `count=XXX`

If the server detects that this section was flooded with an excessive number of errors, it will be disabled, show a single `ERRORSTATS_DISABLED` error, and print the errors to the server log.
This can be reset by `CONFIG RESETSTAT`.

The **hotkeys** section provides information about hotkeys tracking. It consists of the following fields:

*   `tracking_active`: Boolean flag (0 or 1) indicating whether hotkeys tracking is currently active.
*   `used_memory`: Memory overhead in bytes of the structures used for hotkeys tracking.
*   `cpu_time`: Time in milliseconds spent updating the hotkey tracking structures.

The **sentinel** section is only available in Redis Sentinel instances. It consists of the following fields:

*   `sentinel_masters`: Number of Redis masters monitored by this Sentinel instance
*   `sentinel_tilt`: A value of 1 means this sentinel is in TILT mode
*   `sentinel_tilt_since_seconds`: Duration in seconds of current TILT, or -1 if not TILTed. Added in Redis 7.0.0
*   `sentinel_total_tilt`: The number of times this sentinel has been in TILT mode since running.
*   `sentinel_running_scripts`: The number of scripts this Sentinel is currently executing
*   `sentinel_scripts_queue_length`: The length of the queue of user scripts that are pending execution
*   `sentinel_simulate_failure_flags`: Flags for the `SENTINEL SIMULATE-FAILURE` command

The **cluster** section contains a single field:

*   `cluster_enabled`: Indicates whether Redis cluster is enabled.

The **modules** section contains additional information about loaded modules if the modules provide it. The field part of property lines in this section are always prefixed with the module's name.

_Redis Search fields_

*   `search_gc_bytes_collected`: The total amount of memory freed by the garbage collectors from indexes in the shard's memory in bytes. <sup>[3](#tnote-3)</sup>
*   `search_bytes_collected`: The total amount of memory freed by the garbage collectors from indexes in the shard's memory in bytes. Deprecated in 8.0 (renamed `search_gc_bytes_collected`), but still available in older versions. <sup>[1](#tnote-1)</sup>
*   `search_gc_marked_deleted_vectors`: The number of vectors marked as deleted in the vector indexes that have not yet been cleaned. <sup>[3](#tnote-3)</sup>
*   `search_marked_deleted_vectors`: The number of vectors marked as deleted in the vector indexes that have not yet been cleaned. Deprecated in 8.0 (renamed `search_gc_marked_delete_vectors`), but still available in older versions. <sup>[1](#tnote-1)</sup>
*   `search_gc_total_cycles`: The total number of garbage collection cycles executed. <sup>[3](#tnote-3)</sup>
*   `search_total_cycles`: The total number of garbage collection cycles executed. Deprecated in 8.0 (renamed `search_gc_total_cycles`), but still available in older versions. <sup>[1](#tnote-1)</sup>
*   `search_gc_total_docs_not_collected_by_gc`: The number of documents marked as deleted, whose memory has not yet been freed by the garbage collector. <sup>[3](#tnote-3)</sup>
*   `search_total_docs_not_collected_by_gc`: The number of documents marked as deleted, whose memory has not yet been freed by the garbage collector. Deprecated in 8.0 (renamed `search_gc_total_docs_not_collected`), but still available in older versions. <sup>[1](#tnote-1)</sup>
*   `search_gc_total_ms_run`: The total duration of all garbage collection cycles in the shard, measured in milliseconds. <sup>[3](#tnote-3)</sup>
*   `search_total_ms_run`: The total duration of all garbage collection cycles in the shard, measured in milliseconds. Deprecated in 8.0 (renamed `search_gc_total_ms_run`), but still available in older versions. <sup>[1](#tnote-1)</sup>

*   `search_cursors_internal_idle`: The total number of coordinator cursors that are currently holding pending results in the shard. <sup>[3](#tnote-3)</sup>
*   `search_cursors_user_idle`: The total number of cursors that were explicitly requested by users, that are currently holding pending results in the shard. <sup>[3](#tnote-3)</sup>
*   `search_global_idle`: The total number of user and internal cursors currently holding pending results in the shard. Deprecated in 8.0 (split into `search_cursors_internal_idle` and `search_cursors_user_idle`) but still available in older versions. <sup>[1](#tnote-1)</sup>
*   `search_cursors_internal_active`: The total number of coordinator cursors in the shard, either holding pending results or actively executing `FT.CURSOR READ`. <sup>[3](#tnote-3)</sup>
*   `search_cursors_user_active`: The total number of user cursors in the shard, either holding pending results or actively executing `FT.CURSOR READ`. <sup>[3](#tnote-3)</sup>
*   `search_global_total`: The total number of user and internal cursors in the shard, either holding pending results or actively executing `FT.CURSOR READ`. Deprecated in 8.0 (split into `search_cursors_internal_active` and `search_cursors_user_active`), but still available in older versions. <sup>[1](#tnote-1)</sup>
*   `search_number_of_indexes`: The total number of indexes in the shard. <sup>[1](#tnote-1)</sup>
*   `search_number_of_active_indexes`: The total number of indexes running a background indexing and/or background query processing operation. Background indexing refers to vector ingestion process, or in-progress background indexer. <sup>[1](#tnote-1)</sup>
*   `search_number_of_active_indexes_running_queries`: The total count of indexes currently running a background query process. <sup>[1](#tnote-1)</sup>
*   `search_number_of_active_indexes_indexing`: The total count of indexes currently undergoing a background indexing process. Background indexing refers to a vector ingestion process, or an in-progress background indexer. This metric is limited by the number of WORKER threads allocated for writing operations plus the number of indexes. <sup>[1](#tnote-1)</sup>
*   `search_total_active_write_threads`: The total count of background write (indexing) processes currently running in the shard. Background indexing refers to a vector ingestion process, or an in-progress background indexer. This metric is limited by the number of threads allocated for writing operations. <sup>[1](#tnote-1)</sup>
*   `search_fields_text_Text`: The total number of `TEXT` fields across all indexes in the shard. <sup>[1](#tnote-1)</sup>
*   `search_fields_text_Sortable`: The total number of `SORTABLE TEXT` fields across all indexes in the shard. This field appears only if its value is larger than 0. <sup>[1](#tnote-1)</sup>
*   `search_fields_text_NoIndex`: The total number of `NOINDEX TEXT` fields across all indexes in the shard, which are used for sorting only but not indexed. This field appears only if its value is larger than 0. <sup>[1](#tnote-1)</sup>
*   `search_fields_numeric_Numeric`: The total number of `NUMERIC` fields across all indexes in the shard. <sup>[1](#tnote-1)</sup>
*   `search_fields_numeric_Sortable`: The total number of `SORTABLE NUMERIC` fields across all indexes in the shard. This field appears only if its value is larger than 0. <sup>[1](#tnote-1)</sup>
*   `search_fields_numeric_NoIndex`: The total number of `NOINDEX NUMERIC` fields across all indexes in the shard; i.e., used for sorting only but not indexed. This field appears only if its value is larger than 0. <sup>[1](#tnote-1)</sup>
*   `search_fields_tag_Tag`: The total number of `TAG` fields across all indexes in the shard. <sup>[1](#tnote-1)</sup>
*   `search_fields_tag_Sortable`: The total number of `SORTABLE TAG` fields across all indexes in the shard. This field appears only if its value is larger than 0. <sup>[1](#tnote-1)</sup>
*   `search_fields_tag_NoIndex`: The total number of `NOINDEX TAG` fields across all indexes in the shard; i.e., used for sorting only but not indexed. This field appears only if its value is larger than 0. <sup>[1](#tnote-1)</sup>
*   `search_fields_tag_CaseSensitive`: The total number of `CASESENSITIVE TAG` fields across all indexes in the shard. This field appears only if its value is larger than 0. <sup>[1](#tnote-1)</sup>
*   `search_fields_geo_Geo`: The total number of `GEO` fields across all indexes in the shard. <sup>[1](#tnote-1)</sup>
*   `search_fields_geo_Sortable`: The total number of `SORTABLE GEO` fields across all indexes in the shard. This field appears only if its value is larger than 0. <sup>[1](#tnote-1)</sup>
*   `search_fields_geo_NoIndex`: The total number of `NOINDEX GEO` fields across all indexes in the shard; i.e., used for sorting only but not indexed. This field appears only if its value is larger than 0. <sup>[1](#tnote-1)</sup>
*   `search_fields_vector_Vector`: The total number of `VECTOR` fields across all indexes in the shard. <sup>[1](#tnote-1)</sup>
*   `search_fields_vector_Flat`: The total number of `FLAT VECTOR` fields across all indexes in the shard. <sup>[1](#tnote-1)</sup>
*   `search_fields_vector_HNSW`: The total number of `HNSW VECTOR` fields across all indexes in the shard. <sup>[1](#tnote-1)</sup>
*   `search_fields_geoshape_Geoshape`: The total number of `GEOSHAPE` fields across all indexes in the shard. <sup>[2](#tnote-2)</sup>
*   `search_fields_geoshape_Sortable`: The total number of `SORTABLE GEOSHAPE` fields across all indexes in the shard. This field appears only if its value is larger than 0. <sup>[2](#tnote-2)</sup>
*   `search_fields_geoshape_NoIndex`: The total number of `NOINDEX GEOSHAPE` fields across all indexes in the shard; i.e., used for sorting only but not indexed. This field appears only if its value is larger than 0. <sup>[2](#tnote-2)</sup>
*   `search_fields_<field>_IndexErrors`: The total number of indexing failures caused by attempts to index a document containing <field> field. <sup>[1](#tnote-1)</sup>
*   `search_used_memory_vector_index`: The total memory usage of all vector indexes in the shard. <sup>[1](#tnote-1)</sup>
*   `search_used_memory_indexes`: The estimated total memory allocated by all indexes in the shard in bytes (including vector indexes memory accounted in `search_used_memory_vector_index`). <sup>[1](#tnote-1)</sup>
*   `search_used_memory_indexes_human`: The estimated total memory allocated by all indexes in the shard in MB. <sup>[1](#tnote-1)</sup>
*   `search_smallest_memory_index`: The estimated memory usage of the index with the smallest memory usage in the shard in bytes. <sup>[1](#tnote-1)</sup>
*   `search_smallest_memory_index_human`: The estimated memory usage of the index with the smallest memory usage in the shard in MB. <sup>[1](#tnote-1)</sup>
*   `search_largest_memory_index`: The estimated memory usage of the index with the largest memory usage in the shard in bytes. <sup>[1](#tnote-1)</sup>
*   `search_largest_memory_index_human`: The estimated memory usage of the index with the largest memory usage in the shard in MB. <sup>[1](#tnote-1)</sup>
*   `search_total_indexing_time`: The total time spent on indexing operations, excluding the background indexing of vectors in the HNSW graph. <sup>[1](#tnote-1)</sup>
*   `search_bytes_collected`: The total amount of memory freed by the garbage collectors from indexes in the shard memory in bytes. <sup>[1](#tnote-1)</sup>
*   `search_total_cycles`: The total number of garbage collection cycles executed. <sup>[1](#tnote-1)</sup>
*   `search_total_ms_run`: The total duration of all garbage collection cycles in the shard, measured in milliseconds. <sup>[1](#tnote-1)</sup>
*   `search_total_docs_not_collected_by_gc`: The number of documents marked as deleted whose memory has not yet been freed by the garbage collector. <sup>[1](#tnote-1)</sup>
*   `search_marked_deleted_vectors`: The number of vectors marked as deleted in the vector indexes that have not yet been cleaned. <sup>[1](#tnote-1)</sup>
*   `search_total_queries_processed`: The total number of successful query executions (When using cursors, not counting reading from existing cursors) in the shard. <sup>[1](#tnote-1)</sup>
*   `search_total_query_commands`: The total number of successful query command executions (including `FT.SEARCH`, `FT.AGGREGATE`, and `FT.CURSOR READ`). <sup>[1](#tnote-1)</sup>
*   `search_total_query_execution_time_ms`: The cumulative execution time of all query commands, including `FT.SEARCH`, `FT.AGGREGATE`, and `FT.CURSOR` READ, measured in ms. <sup>[1](#tnote-1)</sup>
*   `search_total_active_queries`: The total number of background queries currently being executed in the shard, excluding `FT.CURSOR READ`. <sup>[1](#tnote-1)</sup>
*   `search_errors_indexing_failures`: The total number of indexing failures recorded across all indexes in the shard. <sup>[1](#tnote-1)</sup>
*   `search_errors_for_index_with_max_failures`: The number of indexing failures in the index with the highest count of failures. <sup>[1](#tnote-1)</sup>
*   `search_OOM_indexing_failures_indexes_count`: The number of indexes whose background indexing process failed due to out-of-memory (OOM) conditions. <sup>[2](#tnote-2)</sup>

1. <a name="tnote-1"></a> Available in RediSearch 2.6.
2. <a name="tnote-2"></a> Available in RediSearch 2.8.
3. <a name="tnote-3"></a> Available in RediSearch 8.0.

The **keyspace** section provides statistics on the main dictionary of each database.
The statistics are the number of keys, and the number of keys with an expiration.

For each database, the following line is added:

*   `dbXXX`: `keys=XXX,expires=XXX,avg_ttl=XXX,subexpiry=XXX`

The **keysizes** section provides detailed statistics on the distribution of key sizes for each data type (strings, lists, sets, hashes, and sorted sets) within the dataset. The distribution is tracked using a base-2 logarithmic histogram.

Here's sample output from a two-database instance of Redis:

[code example]

The **debug** section contains experimental metrics, which might change or get removed in future versions.
It won't be included when `INFO` or `INFO ALL` are called, and it is returned only when `INFO DEBUG` is used.

*   `eventloop_duration_aof_sum`: Total time spent on flushing AOF in eventloop in microseconds.
*   `eventloop_duration_cron_sum`: Total time consumption of cron in microseconds (including serverCron and beforeSleep, but excluding IO and AOF flushing).
*   `eventloop_duration_max`: The maximal time spent in a single eventloop cycle in microseconds.
*   `eventloop_cmd_per_cycle_max`: The maximal number of commands processed in a single eventloop cycle.
*   `allocator_allocated_lua`: Total bytes allocated from the allocator specifically for Lua, including internal-fragmentation.
*   `allocator_active_lua`: Total bytes in the allocator active pages specifically for Lua, including external-fragmentation.
*   `allocator_resident_lua`: Total bytes resident (RSS) in the allocator specifically for Lua. This includes pages that can be released to the OS (by `MEMORY PURGE`, or just waiting).
*   `allocator_frag_bytes_lua`: Delta between `allocator_active_lua` and `allocator_allocated_lua`.

[hcgcpgp]: http://code.google.com/p/google-perftools/

**A note about the word slave used in this man page**: Starting with Redis 5, if not for backward compatibility, the Redis project no longer uses the word slave. Unfortunately in this command the word slave is part of the protocol, so we'll be able to remove such occurrences only when this API will be naturally deprecated.

**Modules generated sections**: Starting with Redis 6, modules can inject their information into the `INFO` command. These are excluded by default even when the `all` argument is provided (it will include a list of loaded modules but not their generated info fields). To get these you must use either the `modules` argument or `everything`.

text:
| Redis
Software | Redis
Cloud | Notes |
|:----------------------|:-----------------|:------|
| ✅ Standard
<nobr>✅ Active-Active</nobr> | ✅ Standard
<nobr>✅ Active-Active</nobr> | In Redis Software, `INFO` returns a different set of fields than Redis Open Source.
Not supported for [scripts](). |

Note: key memory usage is different on Redis Software or Redis Cloud active-active databases than on non-active-active databases. This is because memory usage includes some amount of CRDB overhead.

Additionally, for JSON keys, Redis implements a "shared string" mechanism to save memory when the same JSON field names or field values of type string are used more than once (either inter-key or intra-key).
In such cases, instead of storing the field names or values many times, Redis stores them only once. This mechanism is not in place for active-active databases.

On non-active-active databases, `INFO` (Memory > used_memory) reports that the shared memory is counted, but only once for all keys. On active-active databases, there is no shared memory, so if strings are repeated, they are stored multiple times.

**Example**

Suppose you have ten JSON keys, and each key has 5KB of unique content and 5KB of shared content.

For non-active-active databases, `INFO` (used_memory) would report (10 keys * 5KB) + 5KB ~= 55KB. The last term, "+ 5KB", is the size of the shared content.

For active-active databases, `INFO` (used_memory) would report 10 keys * 20KB ~= 200KB. This number includes some amount of CRDB overhead per JSON key.

title: Return information

text:
**RESP2:**

[Bulk string reply](../../develop/reference/protocol-spec#bulk-strings): a map of info fields, one field per line in the form of `<field>:<value>` where the value can be a comma separated map like `<key>=<val>`. Also contains section header lines starting with `#` and blank lines.
Lines can contain a section name (starting with a `#` character) or a property. All the properties are in the form of `field:value` terminated by `\r\n`.

**RESP3:**

[Verbatim string reply](../../develop/reference/protocol-spec#verbatim-strings): a map of info fields, one field per line in the form of `<field>:<value>` where the value can be a comma separated map like `<key>=<val>`. Also contains section header lines starting with `#` and blank lines.
Lines can contain a section name (starting with a `#` character) or a property. All the properties are in the form of `field:value` terminated by `\r\n`.

section_id: notes


title: JSON.ARRAPPEND

summary: Append one or more JSON values into the array at path after the last element in it.

page_type: content

title: Overview

role: overview

text:
Append the JSON values into the array at `path` after the last element in it.

[Examples](#examples)

title: Required arguments

role: content

text:
key

is the key to modify.

path

is the JSONPath to specify.

value

is one or more values to append to one or more arrays.

To specify a string as an array value to append, wrap the quoted string with an additional set of single quotes. Example: `'"silver"'`. For more detailed use, see [Examples](#examples).

title: Examples

role: example

text:
Add a new color to a list of product colors

Create a document for noise-cancelling headphones in black and silver colors.

redis> JSON.SET item:1 $ '{"name":"Noise-cancelling Bluetooth headphones","description":"Wireless Bluetooth headphones with noise-cancelling technology","connection":{"wireless":true,"type":"Bluetooth"},"price":99.98,"stock":25,"colors":["black","silver"]}'
OK

Add `blue` to the end of the `colors` array. `JSON.ARRAPPEND` returns the new length of the `colors` array.

redis> JSON.ARRAPPEND item:1 $.colors '"blue"'
1) (integer) 3

Get the updated value of the `colors` array.

redis> JSON.GET item:1 $.colors
"[[\"black\",\"silver\",\"blue\"]]"

title: Redis Software and Redis Cloud compatibility

text:
| Redis
Software | Redis
Cloud | Notes |
|:----------------------|:-----------------|:------|
| ✅ Supported
 | <nobr>✅ Flexible & Annual</nobr>
✅ Free & Fixed</nobr> |  |

title: Return information

role: returns

text:
**RESP2:**

With `$`-based path argument: [Array reply]() of [integer replies]() or [null replies](), where each element is the array's new length, or `null` if the matching value is not an array.

With `.`-based path argument: [Integer reply]() representing the array's new length, or [null reply]() if the matching value is not an array.

**RESP3:**

With `$`-based path argument (default): [Array reply]() of [integer replies]() or [null replies](), where each element is the array's new length, or `null` if the matching value is not an array.

With `.`-based path argument: [Integer reply]() representing the array's new length, or [null reply]() if the matching value is not an array.

title: See also

role: related

text: [`JSON.ARRINDEX`]() | [`JSON.ARRINSERT`]()

title: Related topics

text:
* [RedisJSON]()
* [Index and search JSON documents]()


title: JSON.ARRINDEX

summary: Returns the index of the first occurrence of a JSON scalar value in the array at path

title: Overview

text:
Search for the first occurrence of a JSON value in an array

[Examples](#examples)

title: Required arguments

text:
key

is key to parse.

path

is JSONPath to specify.

value

is value to find its index in one or more arrays.

To specify a string as an array value to index, wrap the quoted string with an additional set of single quotes. Example: `'"silver"'`. For more detailed use, see [Examples](#examples).

title: Optional arguments

role: parameters

text:
start

is inclusive start value to specify in a slice of the array to search. Default is `0`.

stop

is exclusive stop value to specify in a slice of the array to search, including the last element. Default is `0`. Negative values are interpreted as starting from the end.

Out-of-range indexes round to the array's start and end. An inverse index range (such as the range from 1 to 0) returns unfound or `-1`.

title: Examples

text:
Find the specific place of a color in a list of product colors

Create a document for noise-cancelling headphones in black and silver colors.

redis> JSON.SET item:1 $ '{"name":"Noise-cancelling Bluetooth headphones","description":"Wireless Bluetooth headphones with noise-cancelling technology","connection":{"wireless":true,"type":"Bluetooth"},"price":99.98,"stock":25,"colors":["black","silver"]}'
OK

Add color `blue` to the end of the `colors` array. `JSON.ARRAPEND` returns the array's new size.

redis> JSON.ARRAPPEND item:1 $.colors '"blue"'
1) (integer) 3

Return the new length of the `colors` array.

redis> JSON.GET item:1
"{\"name\":\"Noise-cancelling Bluetooth headphones\",\"description\":\"Wireless Bluetooth headphones with noise-cancelling technology\",\"connection\":{\"wireless\":true,\"type\":\"Bluetooth\"},\"price\":99.98,\"stock\":25,\"colors\":[\"black\",\"silver\",\"blue\"]}"

Get the list of colors for the product.

redis> JSON.GET item:1 '$.colors[*]'
"[\"black\",\"silver\",\"blue\"]"

Insert two more colors after the second color. You now have five colors.

redis> JSON.ARRINSERT item:1 $.colors 2 '"yellow"' '"gold"'
1) (integer) 5

Get the updated list of colors.

redis> JSON.GET item:1 $.colors
"[[\"black\",\"silver\",\"yellow\",\"gold\",\"blue\"]]"

Find the place where color `silver` is located.

redis> JSON.ARRINDEX item:1 $..colors '"silver"'
1) (integer) 1

text:
| Redis
Software | Redis
Cloud | Notes |
|:----------------------|:-----------------|:------|
| ✅ Supported
 | ✅ Flexible & Annual
✅ Free & Fixed</nobr> |  |

title: Return information

text:
**RESP2:**

With `$`-based path argument: [Array reply]() of [integer replies]() or [null replies](), where each element is the first position in the array, `-1` if unfound, or `null` if the matching value is not an array.

With `.`-based path argument: [Integer reply]() representing the first position in the array, `-1` if unfound, or [null reply]() if the matching value is not an array.

**RESP3:**

With `$`-based path argument (default): [Array reply]() of [integer replies]() or [null replies](), where each element is the first position in the array, `-1` if unfound, or `null` if the matching value is not an array.

With `.`-based path argument: [Integer reply]() representing the first position in the array, `-1` if unfound, or [null reply]() if the matching value is not an array.

title: See also

text: [`JSON.ARRAPPEND`]() | [`JSON.ARRINSERT`]()

title: Related topics


title: JSON.ARRINSERT

summary: Inserts the JSON scalar(s) value at the specified index in the array at path

title: Overview

text:
Insert the `json` values into the array at `path` before the `index` (shifts to the right)

[Examples](#examples)

title: Required arguments

text:
key

is key to modify.

value

is one or more values to insert in one or more arrays.

To specify a string as an array value to insert, wrap the quoted string with an additional set of single quotes. Example: `'"silver"'`. For more detailed use, see [Examples](#examples).

index

is position in the array where you want to insert a value. The index must be in the array's range. Inserting at `index` 0 prepends to the array. Negative index values start from the end of the array.

title: Optional arguments

text:
path

is JSONPath to specify. Default is root `$`.

title: Examples

text:
Add new colors to a specific place in a list of product colors

Create a document for noise-cancelling headphones in black and silver colors.

redis> JSON.SET item:1 $ '{"name":"Noise-cancelling Bluetooth headphones","description":"Wireless Bluetooth headphones with noise-cancelling technology","connection":{"wireless":true,"type":"Bluetooth"},"price":99.98,"stock":25,"colors":["black","silver"]}'
OK

Add color `blue` to the end of the `colors` array. `JSON.ARRAPEND` returns the array's new size.

redis> JSON.ARRAPPEND item:1 $.colors '"blue"'
1) (integer) 3

Return the new length of the `colors` array.

redis> JSON.GET item:1
"{\"name\":\"Noise-cancelling Bluetooth headphones\",\"description\":\"Wireless Bluetooth headphones with noise-cancelling technology\",\"connection\":{\"wireless\":true,\"type\":\"Bluetooth\"},\"price\":99.98,\"stock\":25,\"colors\":[\"black\",\"silver\",\"blue\"]}"

Get the list of colors for the product.

redis> JSON.GET item:1 '$.colors[*]'
"[\"black\",\"silver\",\"blue\"]"

Insert two more colors after the second color. You now have five colors.

redis> JSON.ARRINSERT item:1 $.colors 2 '"yellow"' '"gold"'
1) (integer) 5

Get the updated list of colors.

redis> JSON.GET item:1 $.colors
"[[\"black\",\"silver\",\"yellow\",\"gold\",\"blue\"]]"

title: Return information

text:
**RESP2:**

With `$`-based path argument: [Array reply]() of [integer replies]() or [null replies](), where each element is the array's new size, or `null` if the matching value is not an array.

With `.`-based path argument: [Integer reply]() representing the array's new size, or [null reply]() if the matching value is not an array.

**RESP3:**

With `$`-based path argument (default): [Array reply]() of [integer replies]() or [null replies](), where each element is the array's new size, or `null` if the matching value is not an array.

With `.`-based path argument: [Integer reply]() representing the array's new size, or [null reply]() if the matching value is not an array.

title: See also

text: [`JSON.ARRAPPEND`]() | [`JSON.ARRINDEX`]()

title: Related topics


title: JSON.ARRLEN

summary: Returns the length of the array at path

title: Overview

text:
Report the length of the JSON array at `path` in `key`

[Examples](#examples)

title: Required arguments

text:
key

is key to parse.

title: Optional arguments

text:
path

is JSONPath to specify. Default is root `$`, if not provided. Returns null if the `key` or `path` do not exist.

title: Examples

text:
Get lengths of JSON arrays in a document

Create a document for wireless earbuds.

redis> JSON.SET item:2 $ '{"name":"Wireless earbuds","description":"Wireless Bluetooth in-ear headphones","connection":{"wireless":true,"type":"Bluetooth"},"price":64.99,"stock":17,"colors":["black","white"], "max_level":[80, 100, 120]}'
OK

Find lengths of arrays in all objects of the document.

redis> JSON.ARRLEN item:2 '$.[*]'
1) (nil)
2) (nil)
3) (nil)
4) (nil)
5) (nil)
6) (integer) 2
7) (integer) 3

Return the length of the `max_level` array.

redis> JSON.ARRLEN item:2 '$..max_level'
1) (integer) 3

Get all the maximum level values.

redis> JSON.GET item:2 '$..max_level'
"[[80,100,120]]"

title: Return information

text:
**RESP2:**

With `$`-based path argument: [Array reply]() of [integer replies]() or [null replies](), where each element is the array length, or `null` if the matching value is not an array.

With `.`-based path argument: [Integer reply]() representing the array length, or [null reply]() if the matching value is not an array.

**RESP3:**

With `$`-based path argument (default): [Array reply]() of [integer replies]() or [null replies](), where each element is the array length, or `null` if the matching value is not an array.

With `.`-based path argument: [Integer reply]() representing the array length, or [null reply]() if the matching value is not an array.

title: See also

title: Related topics


title: JSON.ARRPOP

summary: Removes and returns the element at the specified index in the array at path

title: Overview

text:
Remove and return an element from the index in the array

[Examples](#examples)

title: Required arguments

text:
key

is key to modify.

index

is position in the array to start popping from. Default is `-1`, meaning the last element. Out-of-range indexes round to their respective array ends. Popping an empty array returns null.

title: Optional arguments

title: Examples

text:
Pop a value from an index and insert a new value

Create two headphone products with maximum sound levels.

redis> JSON.SET key $ '[{"name":"Healthy headphones","description":"Wireless Bluetooth headphones with noise-cancelling technology","connection":{"wireless":true,"type":"Bluetooth"},"price":99.98,"stock":25,"colors":["black","silver"],"max_level":[60,70,80]},{"name":"Noisy headphones","description":"Wireless Bluetooth headphones with noise-cancelling technology","connection":{"wireless":true,"type":"Bluetooth"},"price":99.98,"stock":25,"colors":["black","silver"],"max_level":[80,90,100,120]}]'
OK

Get all maximum values for the second product.

redis> JSON.GET key $.[1].max_level
"[[80,90,100,120]]"

Update the `max_level` field of the product: remove an unavailable value and add a newly available value.

redis> JSON.ARRPOP key $.[1].max_level 0
1) "80"

Get the updated array.

redis> JSON.GET key $.[1].max_level
"[[90,100,120]]"

Now insert a new lowest value.

redis> JSON.ARRINSERT key $.[1].max_level 0 85
1) (integer) 4

Get the updated array.

redis> JSON.GET key $.[1].max_level
"[[85,90,100,120]]"

title: Return information

text:
**RESP2:**

[Array reply]() of [bulk string replies]() or [null replies](), where each element is the popped JSON value as a string, or `null` if the matching value is not an array.

**RESP3:**

[Array reply]() of [bulk string replies]() or [null replies](), where each element is the popped JSON value as a string, or `null` if the matching value is not an array.

title: See also

title: Related topics

text:
* [RedisJSON]()
* [Index and search JSON documents]()


title: JSON.ARRTRIM

summary: Trims the array at path to contain only the specified inclusive range of indices from start to stop

title: Overview

text:
Trim an array so that it contains only the specified inclusive range of elements

[Examples](#examples)

title: Required arguments

text:
key

is key to modify.

title: Optional arguments

text:
path

is JSONPath to specify. Default is root `$`.

start

is index of the first element to keep (previous elements are trimmed). Default is 0.

stop

is the index of the last element to keep (following elements are trimmed), including the last element. Default is 0. Negative values are interpreted as starting from the end.

JSON.ARRTRIM is extremely forgiving, and using it with out-of-range indexes does not produce an error. Note a few differences between how RedisJSON v2.0 and legacy versions handle out-of-range indexes.

Behavior as of RedisJSON v2.0:

* If `start` is larger than the array's size or `start` > `stop`, returns 0 and an empty array.
* If `start` is < 0, then start from the end of the array.
* If `stop` is larger than the end of the array, it is treated like the last element.

title: Examples

text:
Trim an array to a specific set of values

Create two headphone products with maximum sound levels.

redis> JSON.SET key $
"[{\"name\":\"Healthy headphones\",\"description\":\"Wireless Bluetooth headphones with noise-cancelling technology\",\"connection\":{\"wireless\":true,\"type\":\"Bluetooth\"},\"price\":99.98,\"stock\":25,\"colors\":[\"black\",\"silver\"],\"max_level\":[60,70,80]},{\"name\":\"Noisy headphones\",\"description\":\"Wireless Bluetooth headphones with noise-cancelling technology\",\"connection\":{\"wireless\":true,\"type\":\"Bluetooth\"},\"price\":99.98,\"stock\":25,\"colors\":[\"black\",\"silver\"],\"max_level\":[85,90,100,120]}]"
OK

Add new sound level values to the second product.

redis> JSON.ARRAPPEND key $.[1].max_level 140 160 180 200 220 240 260 280
1) (integer) 12

Get the updated array.

redis> JSON.GET key $.[1].max_level
"[[85,90,100,120,140,160,180,200,220,240,260,280]]"

Keep only the values between the fifth and the ninth element, inclusive of that last element.

redis> JSON.ARRTRIM key $.[1].max_level 4 8
1) (integer) 5

Get the updated array.

redis> JSON.GET key $.[1].max_level
"[[140,160,180,200,220]]"

text:
| Redis
Software | Redis
Cloud | Notes |
|:----------------------|:-----------------|:------|
| ✅ Supported
 | ✅ Flexible & Annual
✅ Free & Fixed</nobr> |  |

title: Return information

title: See also

text: [`JSON.ARRINDEX`]() | [`JSON.ARRINSERT`]()

title: Related topics


title: JSON.CLEAR

summary: Clears all values from an array or an object and sets numeric values to `0`

title: Overview

text:
Clear container values (arrays/objects) and set numeric values to `0`

[Examples](#examples)

title: Required arguments

text:
key

is key to parse.

title: Optional arguments

text:
path

is JSONPath to specify. Default is root `$`. Nonexisting paths are ignored.

Already cleared values are ignored for empty containers and zero numbers.

title: Examples

text:
Clear container values and set numeric values to 0

Create a JSON document.

redis> JSON.SET doc $ '{"obj":{"a":1, "b":2}, "arr":[1,2,3], "str": "foo", "bool": true, "int": 42, "float": 3.14}'
OK

Clear all container values. This returns the number of objects with cleared values.

redis> JSON.CLEAR doc $.*
(integer) 4

Get the updated document. Note that numeric values have been set to `0`.

redis> JSON.GET doc $
"[{\"obj\":{},\"arr\":[],\"str\":\"foo\",\"bool\":true,\"int\":0,\"float\":0}]"

title: Return information

text:
**RESP2:**

[Integer reply](): the number of matching JSON arrays and objects cleared plus the number of matching JSON numerical values zeroed.

**RESP3:**

[Integer reply](): the number of matching JSON arrays and objects cleared plus the number of matching JSON numerical values zeroed.

title: See also

title: Related topics


title: JSON.DEBUG

summary: Debugging container command

title: Content

text: This is a container command for debugging related tasks.


title: JSON.DEBUG HELP

summary: Shows helpful information

title: Overview

text: Return helpful information about the [`JSON.DEBUG`]() command

title: Return information

text:
**RESP2:**

[Array reply]() of [bulk string replies]() containing helpful messages about the JSON.DEBUG command.

**RESP3:**

[Array reply]() of [bulk string replies]() containing helpful messages about the JSON.DEBUG command.

title: See also

text: [`JSON.DEBUG`]()

title: Related topics


title: JSON.DEBUG MEMORY

summary: Reports the size in bytes of a key

title: Overview

text:
Report a value's memory usage in bytes

The actual total memory consumption by a key could be much lower than the value reported by this command because of an internal JSON string reuse mechanism. For more information, see the [JSON memory usage page]().

[Examples](#examples)

title: Required arguments

text:
key

is key to parse.

title: Optional arguments

text:
path

is JSONPath to specify. Default is root `$`.

title: Examples

text:
Report a value's memory usage in bytes

Create a JSON document.

redis> JSON.SET item:2 $ '{"name":"Wireless earbuds","description":"Wireless Bluetooth in-ear headphones","connection":{"wireless":true,"type":"Bluetooth"},"price":64.99,"stock":17,"colors":["black","white"], "max_level":[80, 100, 120]}'
OK

Get the values' memory usage in bytes.

redis> JSON.DEBUG MEMORY item:2
(integer) 573

title: Return information

text:
**RESP2:**

[Integer reply](): the value size in bytes.

**RESP3:**

[Integer reply](): the value size in bytes.

title: See also

text: [`JSON.SET`]() | [`JSON.ARRLEN`]()

title: Related topics


title: JSON.DEL

summary: Deletes a value

title: Overview

text:
Delete a value

[Examples](#examples)

title: Required arguments

text:
key

is key to modify.

title: Optional arguments

text:
path

is JSONPath to specify. Default is root `$`. Nonexisting paths are ignored.

Deleting an object's root is equivalent to deleting the key from Redis.

title: Examples

text:
Delete a value

Create a JSON document.

redis> JSON.SET doc $ '{"a": 1, "nested": {"a": 2, "b": 3}}'
OK

Delete specified values.

redis> JSON.DEL doc $..a
(integer) 2

Get the updated document.

redis> JSON.GET doc $
"[{\"nested\":{\"b\":3}}]"

title: Return information

text:
**RESP2:**

[Integer reply](): the number of paths deleted (0 or more).

**RESP3:**

[Integer reply](): the number of paths deleted (0 or more).

title: See also

text: [`JSON.SET`]() | [`JSON.ARRLEN`]()

title: Related topics

text:
* [RedisJSON]()
* [Index and search JSON documents]()


title: JSON.FORGET

summary: Deletes a value

title: Overview

text: See [`JSON.DEL`]().

text:
| Redis
Software | Redis
Cloud | Notes |
|:----------------------|:-----------------|:------|
| ✅ Supported
 | ✅ Flexible & Annual
✅ Free & Fixed</nobr> |  |


title: JSON.GET

summary: Gets the value at one or more paths in JSON serialized form

title: Overview

text:
Return the value at `path` in JSON serialized form

[Examples](#examples)

title: Required arguments

text:
key

is key to parse.

title: Optional arguments

text:
path

is JSONPath to specify. Default is root `$`. JSON.GET accepts multiple `path` arguments.

When using a single JSONPath, the root of the matching values is a JSON string with a top-level **array** of serialized JSON value.
In contrast, a legacy path returns a single value.

When using multiple JSONPath arguments, the root of the matching values is a JSON string with a top-level **object**, with each object value being a top-level array of serialized JSON value.
In contrast, if all paths are legacy paths, each object value is a single serialized JSON value.
If there are multiple paths that include both legacy path and JSONPath, the returned value conforms to the JSONPath version (an array of values).

INDENT

sets the indentation string for nested levels.

NEWLINE

sets the string that's printed at the end of each line.

SPACE

sets the string that's put between a key and a value.

Produce pretty-formatted JSON with `redis-cli` by following this example:

~/$ redis-cli --raw
redis> JSON.GET myjsonkey INDENT "\t" NEWLINE "\n" SPACE " " path.to.value[1]

title: Examples

text:
Return the value at path in JSON serialized form

Create a JSON document.

redis> JSON.SET doc $ '{"a":2, "b": 3, "nested": {"a": 4, "b": null}}'
OK

With a single JSONPath (JSON array bulk string):

redis>  JSON.GET doc $..b
"[3,null]"

Using multiple paths with at least one JSONPath returns a JSON string with a top-level object with an array of JSON values per path:

redis> JSON.GET doc ..a $..b
"{\"$..b\":[3,null],\"..a\":[2,4]}"

title: Return information

text:
**RESP2:**

[Bulk string reply](): a JSON-encoded string representing the value(s) at the specified path(s).

With a single path, returns the JSON serialization of the value at that path.
With multiple paths, returns a JSON object where each key is a path and each value is an array of JSON serializations.

**RESP3:**

[Bulk string reply](): a JSON-encoded string with a top-level array containing the value(s) at the specified path(s).

With a single path using `$` (default in RESP3), returns a JSON array containing the serialized value.
With multiple paths, returns a JSON object where each key is a path and each value is an array of JSON serializations.

title: See also

text: [`JSON.SET`]() | [`JSON.MGET`]()

title: Related topics


title: JSON.MERGE

summary: Merges a given JSON value into matching paths. Consequently, JSON values at matching paths are updated, deleted, or expanded with new children

title: Overview

text:
Merge a given JSON value into matching paths. Consequently, JSON values at matching paths are updated, deleted, or expanded with new children.

This command complies with [RFC7396](https://datatracker.ietf.org/doc/html/rfc7396) Json Merge Patch

[Examples](#examples)

title: Required arguments

text:
key

is the key to merge into.

path

specifies the JSONPath. For non-existing keys the `path` must be `$`. For existing keys, for each matched `path`, the value that matches the `path` is merged with the JSON `value`. For existing keys, when the path exists, except for the last element, a new child is added with the JSON `value`.

value

is the JSON value to merge with at the specified path. Merging is done according to the following rules per JSON value in the `value` argument while considering the corresponding original value if it exists:
*   merging an existing object key with a `null` value deletes the key
*   merging an existing object key with non-null value updates the value
*   merging a non-existing object key adds the key and value
*   merging an existing array with any merged value, replaces the entire array with the value

title: Examples

text:
JSON.MERGE provides four different behaviors to merge changes on a given key: create a non-existent path, update an existing path with a new value, delete an existing path, or replace an array with a new array

Create a non-existent path-value

redis> JSON.SET doc $ '{"a":2}'
OK
redis> JSON.MERGE doc $.b '8'
OK
redis> JSON.GET doc $
"[{\"a\":2,\"b\":8}]"

Replace an existing value

redis> JSON.SET doc $ '{"a":2}'
OK
redis> JSON.MERGE doc $.a '3'
OK
redis> JSON.GET doc $
"[{\"a\":3}]"

Delete an existing value

redis> JSON.SET doc $ '{"a":2}'
OK
redis> JSON.MERGE doc $ '{"a":null}'
OK
redis> JSON.GET doc $
"[{}]"

Replace an Array

redis> JSON.SET doc $ '{"a":[2,4,6,8]}'
OK
redis> JSON.MERGE doc $.a '[10,12]'
OK
redis> JSON.GET doc $
"[{\"a\":[10,12]}]"

Merge changes in multi-paths

redis> JSON.SET doc $ '{"f1": {"a":1}, "f2":{"a":2}}'
OK
redis> JSON.GET doc
"{\"f1\":{\"a\":1},\"f2\":{\"a\":2}}"
redis> JSON.MERGE doc $ '{"f1": null, "f2":{"a":3, "b":4}, "f3":[2,4,6]}'
OK
redis> JSON.GET doc
"{\"f2\":{\"a\":3,\"b\":4},\"f3\":[2,4,6]}"

text:
| Redis
Software | Redis
Cloud | Notes |
|:----------------------|:-----------------|:------|
| ✅ Standard
<nobr>✅ Active-Active</nobr> | ✅ Standard
<nobr>✅ Active-Active</nobr> |  |

title: Return information

text:
**RESP2:**

One of the following:
* [Simple string reply](): `OK` if executed correctly.
* [Simple error reply](): if the operation fails to set the new values.

**RESP3:**

One of the following:
* [Simple string reply](): `OK` if executed correctly.
* [Simple error reply](): if the operation fails to set the new values.

title: See also

text: [`JSON.GET`]() | [`JSON.MGET`]() | [`JSON.SET`]() | [`JSON.MSET`]()

title: Related topics


title: JSON.MGET

summary: Returns the values at a path from one or more keys

title: Overview

text:
This command's behavior varies in clustered Redis environments. See the [multi-key operations]() page for more information.

Return the values at `path` from multiple `key` arguments

When cluster mode is enabled, all specified keys must reside on the same [hash slot](https://redis.io/docs/latest/operate/oss_and_stack/reference/cluster-spec/#key-distribution-model).

When the database has more than one shard, and the specified keys reside in different shards, Redis will not report a CROSSSLOT error (to avoid breaking changes) and the results may be partial.

[Examples](#examples)

title: Required arguments

text:
key

is key to parse. Returns `null` for nonexistent keys.

title: Optional arguments

text:
path

is JSONPath to specify. Returns `null` for nonexistent paths.

title: Examples

text:
Return the values at path from multiple key arguments

Create two JSON documents.

redis> JSON.SET doc1 $ '{"a":1, "b": 2, "nested": {"a": 3}, "c": null}'
OK
redis> JSON.SET doc2 $ '{"a":4, "b": 5, "nested": {"a": 6}, "c": null}'
OK

Get values from all arguments in the documents.

redis> JSON.MGET doc1 doc2 $..a
1) "[1,3]"
2) "[4,6]"

title: Return information

text:
**RESP2:**

[Array reply]() of [bulk string replies]() or [null replies](), where each element is the JSON serialization of the value at the corresponding key's path, or `null` if the key or path doesn't exist.

**RESP3:**

[Array reply]() of [bulk string replies]() or [null replies](), where each element is the JSON serialization of the value at the corresponding key's path, or `null` if the key or path doesn't exist.

title: See also

text: [`JSON.SET`]() | [`JSON.GET`]()

title: Related topics


title: JSON.MSET

summary: Sets or updates the JSON value of one or more keys

title: Overview

text:
This command's behavior varies in clustered Redis environments. See the [multi-key operations]() page for more information.

Set or update one or more JSON values according to the specified `key`-`path`-`value` triplets

`JSON.MSET` is atomic, hence, all given additions or updates are either applied or not. It is not possible for clients to see that some of the keys were updated while others are unchanged.

A JSON value is a hierarchical structure. If you change a value in a specific path - nested values are affected.

When cluster mode is enabled, all specified keys must reside on the same [hash slot](https://redis.io/docs/latest/operate/oss_and_stack/reference/cluster-spec/#key-distribution-model).

[Examples](#examples)

title: Required arguments

text:
key

is key to modify.

path

is JSONPath to specify. For new Redis keys the `path` must be the root. For existing keys, when the entire `path` exists, the value that it contains is replaced with the `json` value. For existing keys, when the `path` exists, except for the last element, a new child is added with the `json` value.

value

is value to set at the specified path

title: Examples

text:
Add a new values in multiple keys

redis> JSON.MSET doc1 $ '{"a":1}' doc2 $ '{"f":{"a":2}}' doc3 $ '{"f1":{"a":0},"f2":{"a":0}}'
OK
redis> JSON.MSET doc1 $ '{"a":2}' doc2 $.f.a '3' doc3 $ '{"f1":{"a":1},"f2":{"a":2}}'
OK
redis> JSON.GET doc1 $
"[{\"a\":2}]"
redis> JSON.GET doc2 $
"[{\"f\":{\"a\":3}}]"
redis> JSON.GET doc3
"{\"f1\":{\"a\":1},\"f2\":{\"a\":2}}"

text:
| Redis
Software | Redis
Cloud | Notes |
|:----------------------|:-----------------|:------|
| ❌ Standard
<nobr>❌ Active-Active</nobr> | ❌ Standard
<nobr>❌ Active-Active</nobr> |  |

title: Return information

title: See also

text: [`JSON.SET`]() | [`JSON.MGET`]() | [`JSON.GET`]()

title: Related topics

text:
* [RedisJSON]()
* [Index and search JSON documents]()


title: JSON.NUMINCRBY

summary: Increments the numeric value at path by a value

title: Overview

text:
Increment the number value stored at `path` by `number`

[Examples](#examples)

title: Required arguments

text:
key

is key to modify.

path

is JSONPath to specify.

value

is number value to increment.

title: Examples

text:
Increment number values

Create a document.

redis> JSON.SET doc . '{"a":"b","b":[{"a":2}, {"a":5}, {"a":"c"}]}'
OK

Increment a value of `a` object by 2. The command fails to find a number and returns `null`.

redis> JSON.NUMINCRBY doc $.a 2
"[null]"

Recursively find and increment a value of all `a` objects. The command increments numbers it finds and returns `null` for nonnumber values.

redis> JSON.NUMINCRBY doc $..a 2
"[null,4,7,null]"

text:
| Redis
Software | Redis
Cloud | Notes |
|:----------------------|:-----------------|:------|
| ✅ Supported
 | ✅ Flexible & Annual
✅ Free & Fixed</nobr> |  |

title: Return information

text:
**RESP2:**

With `$`-based path argument: [Bulk string reply]() containing a JSON-encoded string with the new value(s), or [null reply]() if the matching value is not a number.

With `.`-based path argument: [Bulk string reply]() representing the stringified new value, [null reply]() if the matching value is not a number, or [simple error reply]() on error.

**RESP3:**

With `$`-based path argument (default): [Array reply]() of [integer replies]() or [null replies](), where each element is the new value, or `null` if the matching value is not a number, or [simple error reply]() on error.

With `.`-based path argument: [Bulk string reply]() representing the stringified new value, [null reply]() if the matching value is not a number, or [simple error reply]() on error.

title: See also

text: [`JSON.ARRINDEX`]() | [`JSON.ARRINSERT`]()

title: Related topics


title: JSON.NUMMULTBY

summary: Multiplies the numeric value at path by a value

title: Overview

text:
Multiply the number value stored at `path` by `number`

[Examples](#examples)

title: Required arguments

text:
key

is key to modify.

value

is number value to multiply.

title: Optional arguments

text:
path

is JSONPath to specify. Default is root `$`.

title: Examples

text:
redis> JSON.SET doc . '{"a":"b","b":[{"a":2}, {"a":5}, {"a":"c"}]}'
OK
redis> JSON.NUMMULTBY doc $.a 2
"[null]"
redis> JSON.NUMMULTBY doc $..a 2
"[null,4,10,null]"

title: Return information

title: See also

text: [`JSON.NUMINCRBY`]() | [`JSON.ARRINSERT`]()

title: Related topics


title: JSON.OBJKEYS

summary: Returns the JSON keys of the object at path

title: Overview

text:
Return the keys in the object that's referenced by `path`

[Examples](#examples)

title: Required arguments

text:
key

is key to parse. Returns `null` for nonexistent keys.

title: Optional arguments

text:
path

is JSONPath to specify. Default is root `$`. Returns `null` for nonexistant path.

title: Examples

text:
redis> JSON.SET doc $ '{"a":[3], "nested": {"a": {"b":2, "c": 1}}}'
OK
redis> JSON.OBJKEYS doc $..a
1) (nil)
2) 1) "b"
   2) "c"

title: Return information

text:
**RESP2:**

With `$`-based path argument: [Array reply]() of [array replies]() of [bulk string replies](), where each nested array contains the key names in the object, or `null` if the matching value is not an object.

With `.`-based path argument: [Array reply]() of [bulk string replies]() containing the key names in the object, or [null reply]() if the matching value is not an object.

**RESP3:**

With `$`-based path argument (default): [Array reply]() of [array replies]() of [bulk string replies](), where each nested array contains the key names in the object, or `null` if the matching value is not an object.

With `.`-based path argument: [Array reply]() of [bulk string replies]() containing the key names in the object, or [null reply]() if the matching value is not an object.

title: See also

title: Related topics


title: JSON.OBJLEN

summary: Returns the number of keys of the object at path

title: Overview

text:
Report the number of keys in the JSON object at `path` in `key`

[Examples](#examples)

title: Required arguments

title: Optional arguments

title: Examples

text:
redis> JSON.SET doc $ '{"a":[3], "nested": {"a": {"b":2, "c": 1}}}'
OK
redis> JSON.OBJLEN doc $..a
1) (nil)
2) (integer) 2

title: Return information

text:
**RESP2:**

With `$`-based path argument: [Array reply]() of [integer replies]() or [null replies](), where each element is the number of keys in the object, or `null` if the matching value is not an object.

With `.`-based path argument: [Integer reply]() representing the number of keys in the object, or [null reply]() if the matching value is not an object.

**RESP3:**

With `$`-based path argument (default): [Array reply]() of [integer replies]() or [null replies](), where each element is the number of keys in the object, or `null` if the matching value is not an object.

With `.`-based path argument: [Integer reply]() representing the number of keys in the object, or [null reply]() if the matching value is not an object.

title: See also

title: Related topics

text:
* [RedisJSON]()
* [Index and search JSON documents]()


title: JSON.RESP

summary: Returns the JSON value at path in Redis Serialization Protocol (RESP)

title: Overview

text:
Return the JSON in `key` in [Redis serialization protocol specification]() form

[Examples](#examples)

title: Required arguments

text:
key

is key to parse.

title: Optional arguments

text:
path

is JSONPath to specify. Default is root `$`. This command uses the following mapping from JSON to RESP:

*   JSON `null` maps to the bulk string reply.
*   JSON `false` and `true` values map to the simple string reply.
*   JSON number maps to the integer reply or bulk string reply, depending on type.
*   JSON string maps to the bulk string reply.
*   JSON array is represented as an array reply in which the first element is the simple string reply `[`, followed by the array's elements.
*   JSON object is represented as an array reply in which the first element is the simple string reply `{`. Each successive entry represents a key-value pair as a two-entry array reply of the bulk string reply.

For more information about replies, see [Redis serialization protocol specification]().

title: Examples

text:
Return an array of RESP details about a document

Create a JSON document.

redis> JSON.SET item:2 $ '{"name":"Wireless earbuds","description":"Wireless Bluetooth in-ear headphones","connection":{"wireless":true,"type":"Bluetooth"},"price":64.99,"stock":17,"colors":["black","white"], "max_level":[80, 100, 120]}'
OK

Get all RESP details about the document.

redis> JSON.RESP item:2
 1) {
 2) "name"
 3) "Wireless earbuds"
 4) "description"
 5) "Wireless Bluetooth in-ear headphones"
 6) "connection"
 7) 1) {
    2) "wireless"
    3) true
    4) "type"
    5) "Bluetooth"
 8) "price"
 9) "64.989999999999995"
10) "stock"
11) (integer) 17
12) "colors"
13) 1) [
    2) "black"
    3) "white"
14) "max_level"
15) 1) [
    2) (integer) 80
    3) (integer) 100
    4) (integer) 120

text:
| Redis
Software | Redis
Cloud | Notes |
|:----------------------|:-----------------|:------|
| ✅ Supported
 | ✅ Flexible & Annual
✅ Free & Fixed</nobr> |  |

title: Return information

text:
**RESP2:**

[Array reply]() representing the JSON value in RESP form, as detailed in the [Redis serialization protocol specification](). The mapping from JSON to RESP follows the rules described in the command arguments.

**RESP3:**

[Array reply]() representing the JSON value in RESP form, as detailed in the [Redis serialization protocol specification](). The mapping from JSON to RESP follows the rules described in the command arguments.

title: See also

text: [`JSON.SET`]() | [`JSON.ARRLEN`]()

title: Related topics


title: JSON.SET

summary: Sets or updates the JSON value at a path

title: Overview

text:
Set or replace the value at each location resolved by `path`.

If the key does not exist, a new JSON document can be created only by setting the root path (`$` or `.`).

`JSON.SET` can also create new object members when the parent object exists.

[Examples](#examples)

title: Required arguments

text:
key

is a new key to create or an existing JSON key to modify.

path

A JSONPath expression that resolves to zero or more locations within the JSON document.

- The root of the document is specified as `$` or `.`.
- If `path` resolves to one or more existing locations, the value at each matched location is replaced with `value`.
- If the final token of `path` is a non-existing object member and the parent location exists and is an object, the member is created and set to `value`.
- If any intermediate path element does not exist, the path cannot be created, and the command returns nil.

Optional arguments `NX` and `XX` modify this behavior for both new keys and existing JSON keys.

value

A valid JSON value to set at the specified path.

The value can be a scalar (string, number, boolean, or null) or a compound value such as an object or array.

title: Optional arguments

text:
NX

Sets the value only if `path` has no matches.

XX

Sets the value only if `path` has one or more matches.

title: Examples

text:
Replace an existing value

redis> JSON.SET doc $ '{"a":2}'
OK
redis> JSON.SET doc $.a '3'
OK
redis> JSON.GET doc $
"[{\"a\":3}]"

Add a new value

redis> JSON.SET doc $ '{"a":2}'
OK
redis> JSON.SET doc $.b '8'
OK
redis> JSON.GET doc $
"[{\"a\":2,\"b\":8}]"

Update multiple matches

redis> JSON.SET doc $ '{"f1": {"a":1}, "f2":{"a":2}}'
OK
redis> JSON.SET doc $..a 3
OK
redis> JSON.GET doc
"{\"f1\":{\"a\":3},\"f2\":{\"a\":3}}"

path does not exist and cannot be created

redis> JSON.SET doc $ 1
OK
redis> JSON.SET doc $.x.y 2
(nil)

XX condition unmet

redis> JSON.SET nonexistentkey $ 5 XX
(nil)
redis> JSON.GET nonexistentkey
(nil)

key does not exist and path is not root

redis> JSON.SET nonexistentkey $.x 5
(error) ERR new objects must be created at the root

title: Return information

text:
**RESP2:**

One of the following:
* [Simple string reply](): `OK` if executed correctly.
* [Null reply](): if `key` exists but `path` does not exist and cannot be created, or if an `NX` or `XX` condition is unmet.
* [Simple error reply](): `(error) expected ...` - if the value is invalid.
* [Simple error reply](): `(error) Error occurred on position ... expected ...` - if the path is invalid.
* [Simple error reply](): `(error) ERR new objects must be created at the root` - if `key` does not exist and `path` is not root (`$` or `.`).
* [Simple error reply](): `(error) ERR wrong static path` - if a dynamic path expression has no matching locations.
* [Simple error reply](): `(error) ERR index out of bounds` - if the path refers to an array index outside the array bounds.

**RESP3:**

One of the following:
* [Simple string reply](): `OK` if executed correctly.
* [Null reply](): if `key` exists but `path` does not exist and cannot be created, or if an `NX` or `XX` condition is unmet.
* [Simple error reply](): `(error) expected ...` - if the value is invalid.
* [Simple error reply](): `(error) Error occurred on position ... expected ...` - if the path is invalid.
* [Simple error reply](): `(error) ERR new objects must be created at the root` - if `key` does not exist and `path` is not root (`$` or `.`).
* [Simple error reply](): `(error) ERR wrong static path` - if a dynamic path expression has no matching locations.
* [Simple error reply](): `(error) ERR index out of bounds` - if the path refers to an array index outside the array bounds.

title: See also

text: [`JSON.GET`]() | [`JSON.MGET`]()

title: Related topics


title: JSON.STRAPPEND

summary: Appends a string to a JSON string value at path

title: Overview

text:
Append the `json-string` values to the string at `path`

[Examples](#examples)

title: Required arguments

text:
key

is key to modify.

value

is value to append to one or more strings.

To specify a string as an array value to append, wrap the quoted string with an additional set of single quotes. Example: `'"silver"'`. For more detailed use, see [Examples](#examples).

title: Optional arguments

text:
path

is JSONPath to specify. Default is root `$`.

title: Examples

text:
redis> JSON.SET doc $ '{"a":"foo", "nested": {"a": "hello"}, "nested2": {"a": 31}}'
OK
redis> JSON.STRAPPEND doc $..a '"baz"'
1) (integer) 6
2) (integer) 8
3) (nil)
redis> JSON.GET doc $
"[{\"a\":\"foobaz\",\"nested\":{\"a\":\"hellobaz\"},\"nested2\":{\"a\":31}}]"

title: Return information

text:
**RESP2:**

With `$`-based path argument: [Array reply]() of [integer replies]() or [null replies](), where each element is the string's new length, or `null` if the matching value is not a string.

With `.`-based path argument: [Integer reply]() representing the string's new length, or [null reply]() if the matching value is not a string.

**RESP3:**

With `$`-based path argument (default): [Array reply]() of [integer replies]() or [null replies](), where each element is the string's new length, or `null` if the matching value is not a string.

With `.`-based path argument: [Integer reply]() representing the string's new length, or [null reply]() if the matching value is not a string.

title: See also

text: `JSON.ARRAPEND` | [`JSON.ARRINSERT`]()

title: Related topics


title: JSON.STRLEN

summary: Returns the length of the JSON String at path in key

title: Overview

text:
Report the length of the JSON String at `path` in `key`

[Examples](#examples)

title: Required arguments

text:
key

is key to parse.

title: Optional arguments

text:
path

is JSONPath to specify. Default is root `$`, if not provided. Returns null if the `key` or `path` do not exist.

title: Examples

text:
redis> JSON.SET doc $ '{"a":"foo", "nested": {"a": "hello"}, "nested2": {"a": 31}}'
OK
redis> JSON.STRLEN doc $..a
1) (integer) 3
2) (integer) 5
3) (nil)

title: Return information

text:
**RESP2:**

With `$`-based path argument: [Array reply]() of [integer replies]() or [null replies](), where each element is the string's length, or `null` if the matching value is not a string.

With `.`-based path argument: [Integer reply]() representing the string's length, or [null reply]() if the matching value is not a string.

**RESP3:**

With `$`-based path argument (default): [Array reply]() of [integer replies]() or [null replies](), where each element is the string's length, or `null` if the matching value is not a string.

With `.`-based path argument: [Integer reply]() representing the string's length, or [null reply]() if the matching value is not a string.

title: See also

text: [`JSON.ARRLEN`]() | [`JSON.ARRINSERT`]()

title: Related topics


title: JSON.TOGGLE

summary: Toggles a boolean value

title: Overview

text:
Toggle a Boolean value stored at `path`

[Examples](#examples)

title: Required arguments

text:
key

is key to modify.

title: Optional arguments

title: Examples

text:
Toggle a Boolean value stored at path

Create a JSON document.

redis> JSON.SET doc $ '{"bool": true}'
OK

Toggle the Boolean value.

redis> JSON.TOGGLE doc $.bool
1) (integer) 0

Get the updated document.

redis> JSON.GET doc $
"[{\"bool\":false}]"

Toggle the Boolean value.

redis> JSON.TOGGLE doc $.bool
1) (integer) 1

Get the updated document.

redis> JSON.GET doc $
"[{\"bool\":true}]"

text:
| Redis
Software | Redis
Cloud | Notes |
|:----------------------|:-----------------|:------|
| ✅ Supported
 | ✅ Flexible & Annual
✅ Free & Fixed</nobr> |  |

title: Return information

text:
**RESP2:**

With `$`-based path argument: [Array reply]() of [integer replies]() or [null replies](), where each element is the new value (`0` if `false` or `1` if `true`), or `null` if the matching value is not Boolean.

With `.`-based path argument: [Integer reply]() representing the new value (`0` if `false` or `1` if `true`), or [null reply]() if the matching value is not Boolean.

**RESP3:**

With `$`-based path argument (default): [Array reply]() of [integer replies]() or [null replies](), where each element is the new value (`0` if `false` or `1` if `true`), or `null` if the matching value is not Boolean.

With `.`-based path argument: [Integer reply]() representing the new value (`0` if `false` or `1` if `true`), or [null reply]() if the matching value is not Boolean.

title: See also

text: [`JSON.SET`]() | [`JSON.GET`]()

title: Related topics

text:
* [RedisJSON]()
* [Index and search JSON documents]()


title: JSON.TYPE

summary: Returns the type of the JSON value at path

title: Overview

text:
Report the type of JSON value at `path`

[Examples](#examples)

title: Required arguments

text:
key

is key to parse.

title: Optional arguments

text:
path

is JSONPath to specify. Default is root `$`. Returns null if the `key` or `path` do not exist.

title: Examples

text:
redis> JSON.SET doc $ '{"a":2, "nested": {"a": true}, "foo": "bar"}'
OK
redis> JSON.TYPE doc $..foo
1) "string"
redis> JSON.TYPE doc $..a
1) "integer"
2) "boolean"
redis> JSON.TYPE doc $..dummy
(empty array)

title: Return information

text:
**RESP2:**

With `$`-based path argument: [Array reply]() of [bulk string replies](), where each element is the type of the matching value.

With `.`-based path argument: [Bulk string reply]() representing the type of the matching value.

**RESP3:**

With `$`-based path argument (default): [Array reply]() of [array replies]() of [bulk string replies](), where each nested array contains the type of the matching value.

With `.`-based path argument: [Array reply]() of [bulk string replies]() representing the type of the matching value.

title: See also

text: [`JSON.SET`]() | [`JSON.ARRLEN`]()

title: Related topics