Skip to main content
Redis JSON provides native JSON document storage with atomic operations, JSONPath queries, and efficient updates. It’s part of the Redis modules and requires compilation with BUILD_WITH_MODULES=yes.
JSON support requires building Redis with BUILD_WITH_MODULES=yes. See the installation guide for details.

Use Cases

  • Document database: Store and query JSON documents
  • User profiles: Complex nested user data
  • Product catalogs: Rich product information
  • Configuration storage: Application settings
  • API caching: Cache JSON API responses
  • Event data: Structured event payloads

Key Commands

Basic Operations

# Set JSON document
redis> JSON.SET user:1001 $ '{"name":"Alice","email":"[email protected]","age":30}'
OK

# Get entire document
redis> JSON.GET user:1001
"{\"name\":\"Alice\",\"email\":\"[email protected]\",\"age\":30}"

# Get specific field
redis> JSON.GET user:1001 $.name
"[\"Alice\"]"

# Get multiple paths
redis> JSON.GET user:1001 $.name $.email
"{\"$.name\":[\"Alice\"],\"$.email\":[\"[email protected]\"]}"

# Delete document
redis> JSON.DEL user:1001
(integer) 1

Path Operations

# Set nested value
redis> JSON.SET user:1001 $ '{"name":"Alice","address":{"city":"NYC"}}'
OK

# Update nested field
redis> JSON.SET user:1001 $.address.zip "10001"
OK

# Get nested value
redis> JSON.GET user:1001 $.address.city
"[\"NYC\"]"

# Delete path
redis> JSON.DEL user:1001 $.address.zip
(integer) 1

Array Operations

# Set document with array
redis> JSON.SET user:1001 $ '{"name":"Alice","tags":["developer","redis"]}'
OK

# Append to array
redis> JSON.ARRAPPEND user:1001 $.tags '"python"'
[3]

# Insert into array
redis> JSON.ARRINSERT user:1001 $.tags 0 '"senior"'
[4]

# Get array length
redis> JSON.ARRLEN user:1001 $.tags
[4]

# Pop from array
redis> JSON.ARRPOP user:1001 $.tags -1
"\"python\""

# Trim array
redis> JSON.ARRTRIM user:1001 $.tags 0 1
[2]

Numeric Operations

# Set numeric field
redis> JSON.SET stats $ '{"views":100,"likes":25}'
OK

# Increment
redis> JSON.NUMINCRBY stats $.views 1
"[101]"

# Multiply
redis> JSON.NUMMULTBY stats $.likes 2
"[50]"

String Operations

# Append to string
redis> JSON.SET user:1001 $ '{"name":"Alice"}'
OK
redis> JSON.STRAPPEND user:1001 $.name '" Smith"'
[11]

# Get string length
redis> JSON.STRLEN user:1001 $.name
[11]

JSONPath Syntax

Redis JSON supports JSONPath for querying:
  • $: Root
  • .key: Child member
  • [index]: Array index
  • [*]: All array elements
  • ..key: Recursive descent
  • [?(@.key > value)]: Filter expressions
# Complex document
redis> JSON.SET products $ '[
  {"id":1,"name":"Redis Book","price":29.99,"inStock":true},
  {"id":2,"name":"JSON Guide","price":19.99,"inStock":false}
]'
OK

# Get all names
redis> JSON.GET products $[*].name
"[\"Redis Book\",\"JSON Guide\"]"

# Get in-stock products
redis> JSON.GET products $[?(@.inStock==true)]
"[{\"id\":1,\"name\":\"Redis Book\",\"price\":29.99,\"inStock\":true}]"

Time Complexity

CommandTime ComplexityDescription
JSON.SETO(M+N)M=path, N=value size
JSON.GETO(M+N)M=path, N=result size
JSON.DELO(N)N=keys deleted
JSON.ARRAPPENDO(1)Append to array
JSON.ARRINSERTO(N)N=array size
JSON.ARRLENO(1)Get array length
JSON.NUMINCRBYO(1)Increment number
JSON.STRLENO(1)Get string length

Patterns and Examples

User Profile

# Create profile
redis> JSON.SET profile:alice $ '{
  "username": "alice",
  "email": "[email protected]",
  "preferences": {
    "theme": "dark",
    "notifications": true
  },
  "tags": ["developer", "redis"],
  "stats": {
    "posts": 42,
    "followers": 156
  }
}'
OK

# Update preference
redis> JSON.SET profile:alice $.preferences.theme '"light"'
OK

# Add tag
redis> JSON.ARRAPPEND profile:alice $.tags '"python"'
[3]

# Increment post count
redis> JSON.NUMINCRBY profile:alice $.stats.posts 1
"[43]"

# Get specific fields
redis> JSON.GET profile:alice $.username $.stats.posts
"{\"$.username\":[\"alice\"],\"$.stats.posts\":[43]}"

Product Catalog

# Add product
redis> JSON.SET product:2001 $ '{
  "id": 2001,
  "name": "Redis Book",
  "description": "Comprehensive Redis guide",
  "price": 29.99,
  "stock": 150,
  "categories": ["books", "database", "redis"],
  "metadata": {
    "author": "John Doe",
    "pages": 350,
    "isbn": "123-456-789"
  },
  "reviews": []
}'
OK

# Update stock
redis> JSON.NUMINCRBY product:2001 $.stock -1
"[149]"

# Add review
redis> JSON.ARRAPPEND product:2001 $.reviews '{
  "user": "alice",
  "rating": 5,
  "comment": "Excellent!"
}'
[1]

# Update price
redis> JSON.SET product:2001 $.price 24.99
OK

API Response Caching

# Cache API response
redis> JSON.SET cache:api:/users/123 $ '{
  "data": {
    "id": 123,
    "name": "Alice",
    "email": "[email protected]"
  },
  "meta": {
    "cached_at": 1709467200,
    "ttl": 3600
  }
}'
OK

# Set expiration
redis> EXPIRE cache:api:/users/123 3600
(integer) 1

# Get cached data
redis> JSON.GET cache:api:/users/123 $.data

Configuration Management

# Store app config
redis> JSON.SET config:app $ '{
  "database": {
    "host": "localhost",
    "port": 5432,
    "pool_size": 10
  },
  "cache": {
    "enabled": true,
    "ttl": 3600
  },
  "features": {
    "beta_features": ["feature1", "feature2"]
  }
}'
OK

# Update config value
redis> JSON.SET config:app $.cache.ttl 7200
OK

# Toggle feature
redis> JSON.SET config:app $.cache.enabled false
OK

# Get config section
redis> JSON.GET config:app $.database

JSON vs String

OperationJSON ModuleString (serialized JSON)
Update fieldDirect path updateDeserialize, update, serialize
Query nestedJSONPathDeserialize entire object
AtomicityAtomic operationsManual locking
PerformanceFaster for updatesFaster for full reads
MemoryOptimizedStandard

Best Practices

  1. Use JSONPath for efficient nested updates
  2. Set expiration on cached documents
  3. Keep documents focused - avoid very large documents
  4. Index with RediSearch for complex queries
  5. Use atomic operations instead of get-modify-set
For complex queries across multiple documents, combine Redis JSON with RediSearch to create indexes and perform full-text search, aggregations, and filtering.
Very large JSON documents (over 1MB) can impact performance. Consider splitting into multiple keys or using compression.

Integration with RediSearch

Combine JSON with RediSearch for powerful querying:
# Create index on JSON documents
redis> FT.CREATE idx:users ON JSON PREFIX 1 user: SCHEMA 
  $.name AS name TEXT 
  $.email AS email TAG 
  $.age AS age NUMERIC

# Search users
redis> FT.SEARCH idx:users "@age:[25 35]" RETURN 3 $.name $.email $.age

Next Steps

Query Engine

Search and index JSON documents

Hashes

For simpler key-value objects

Build docs developers (and LLMs) love