Redis JSON

JSON is the format most web and mobile apps use to exchange data. Redis JSON stores a JSON document as a real structure instead of one block of text. You can read or change a single field deep inside the document without loading the whole thing.

The Filing Folder Analogy

A Hash is a single sheet of paper with a list of labeled lines. A JSON document is a folder with sheets inside, and some sheets hold smaller folders. You can open the folder, pull one sheet, change one line, and put it back without touching the rest.

  Key: user:1
  ┌─────────────────────────────────────────┐
  │ $ (root)                                │
  │  ├─ name:    "Asha"                     │
  │  ├─ age:     29                         │
  │  ├─ address:                            │
  │  │    ├─ city:  "Pune"                  │
  │  │    └─ pin:   "411001"                │
  │  └─ skills:  ["sql", "redis"]           │
  └─────────────────────────────────────────┘

Paths with JSONPath

A path points to a spot inside the document. The dollar sign means the root.

Path                  Points To
────────────────────  ───────────────────────
$                     The whole document
$.name                The name field
$.address.city        The city inside address
$.skills[0]           The first skill
$.skills[*]           Every skill

JSON.SET and JSON.GET

127.0.0.1:6379> JSON.SET user:1 $ '{"name":"Asha","age":29,"address":{"city":"Pune"},"skills":["sql","redis"]}'
OK
127.0.0.1:6379> JSON.GET user:1 $.name
"[\"Asha\"]"
127.0.0.1:6379> JSON.GET user:1 $.address.city
"[\"Pune\"]"

Path queries that start with $ always return an array of matches, so the answer wraps the name in square brackets.

Changing Parts of a Document

127.0.0.1:6379> JSON.NUMINCRBY user:1 $.age 1
"[30]"
127.0.0.1:6379> JSON.ARRAPPEND user:1 $.skills '"python"'
1) (integer) 3
127.0.0.1:6379> JSON.SET user:1 $.address.city '"Mumbai"'
OK

Each command runs as one atomic step. Two servers can raise the age at the same moment, and Redis applies both changes correctly.

Removing Parts

127.0.0.1:6379> JSON.DEL user:1 $.address
(integer) 1
127.0.0.1:6379> JSON.TYPE user:1 $.skills
1) "array"

Reading Several Fields at Once

JSON.GET accepts more than one path. Redis returns a single JSON object that holds one entry per path.

127.0.0.1:6379> JSON.GET user:1 $.name $.age
"{\"$.name\":[\"Asha\"],\"$.age\":[30]}"

MGET-style reads across many keys work too. JSON.MGET takes several keys and one path, which suits list pages that show one field from many documents.

127.0.0.1:6379> JSON.MGET user:1 user:2 $.name
1) "[\"Asha\"]"
2) "[\"Ravi\"]"

JSON versus Hash versus String

Feature                    String (text)   Hash          JSON
─────────────────────────  ──────────────  ────────────  ────────────
Nested data                Text only       No            Yes
Change one inner field     Rewrite all     Yes (flat)    Yes (any depth)
Atomic number increment    No              Yes           Yes
Works with Search index    No              Yes           Yes
Best for                   Simple values   Flat objects  Documents

Pick a Hash for flat records with simple fields. Pick JSON when the data has lists or nested objects.

Practical Example – Product Catalog

Each product lives in one JSON key.

JSON.SET product:501 $ '{"name":"Desk Lamp","price":899,"tags":["home","light"],"stock":{"pune":12,"delhi":7}}'

Sale starts:
  JSON.SET product:501 $.price 749

A customer buys one lamp in Pune:
  JSON.NUMINCRBY product:501 $.stock.pune -1

Add a tag:
  JSON.ARRAPPEND product:501 $.tags '"gift"'

The app never downloads or rewrites the whole product.

Tips for Good JSON Design

  • Keep each document a reasonable size. Giant documents slow replication and snapshots.
  • Store one entity per key, such as one user or one product.
  • Combine JSON with Redis Search to query fields across many documents.
  • Set a TTL with EXPIRE when the document represents temporary data.

Key Points

  • Redis JSON keeps documents as structured data that Redis understands.
  • Paths starting with $ select any spot inside the document.
  • JSON.SET, JSON.GET, JSON.DEL, JSON.NUMINCRBY, and JSON.ARRAPPEND cover daily work.
  • Partial updates run atomically and avoid full rewrites.