Skip to main content
Redis hashes are maps between string fields and string values. They’re ideal for representing objects and storing multiple related values under a single key.

HSET

Sets field-value pairs in a hash. Creates the key if it doesn’t exist.

Syntax

HSET key field value [field value ...]
key
key
required
The hash key. Created if it doesn’t exist.
field
string
required
The field name to set.
value
string
required
The value to set for the field.
count
integer
The number of fields that were added (not including updates to existing fields).
Time Complexity: O(1) for each field/value pair added, so O(N) for N pairs. History:
  • 4.0.0: Accepts multiple field and value arguments.

Examples

redis> HSET myhash field1 "Hello"
(integer) 1
redis> HGET myhash field1
"Hello"
redis> HSET myhash field2 "World" field3 "!"
(integer) 2
redis> HGETALL myhash
1) "field1"
2) "Hello"
3) "field2"
4) "World"
5) "field3"
6) "!"

HGET

Returns the value of a field in a hash.

Syntax

HGET key field
key
key
required
The hash key.
field
string
required
The field name to retrieve.
value
string
The value associated with field, or nil if field doesn’t exist.
Time Complexity: O(1)

Examples

redis> HSET myhash field1 "foo"
(integer) 1
redis> HGET myhash field1
"foo"
redis> HGET myhash field2
(nil)

HGETALL

Returns all fields and values in a hash.

Syntax

HGETALL key
key
key
required
The hash key.
fields
array
Array of field-value pairs (field1, value1, field2, value2, …).
Time Complexity: O(N) where N is the size of the hash.
HGETALL loads all fields into memory. For large hashes, use HSCAN to iterate incrementally.

Examples

redis> HSET myhash field1 "Hello" field2 "World"
(integer) 2
redis> HGETALL myhash
1) "field1"
2) "Hello"
3) "field2"
4) "World"

HINCRBY

Increments the integer value of a hash field by the given number.

Syntax

HINCRBY key field increment
key
key
required
The hash key.
field
string
required
The field to increment.
increment
integer
required
The increment value (can be negative).
value
integer
The value of the field after incrementing.
Time Complexity: O(1)

Examples

redis> HSET myhash field 5
(integer) 1
redis> HINCRBY myhash field 1
(integer) 6
redis> HINCRBY myhash field -1
(integer) 5
redis> HINCRBY myhash field -10
(integer) -5

Additional Hash Commands

  • HMGET: Get multiple field values
  • HMSET: Set multiple fields (deprecated, use HSET)
  • HSETNX: Set field only if it doesn’t exist
  • HDEL: Delete one or more fields
  • HEXISTS: Check if field exists
  • HKEYS: Get all field names
  • HVALS: Get all values
  • HLEN: Get number of fields
  • HSTRLEN: Get length of field value
  • HINCRBYFLOAT: Increment by float
  • HSCAN: Iterate fields
  • HRANDFIELD: Get random field(s)

Use Cases

User Profile

Store user information:
redis> HSET user:1000 username "alice" email "[email protected]" age "30"
(integer) 3
redis> HGET user:1000 username
"alice"
redis> HGETALL user:1000
1) "username"
2) "alice"
3) "email"
4) "[email protected]"
5) "age"
6) "30"
redis> HINCRBY user:1000 age 1
(integer) 31

Session Store

Store session data:
redis> HSET session:abc123 user_id "1000" created "1640000000" last_seen "1640010000"
(integer) 3
redis> EXPIRE session:abc123 1800
(integer) 1
redis> HGET session:abc123 user_id
"1000"

Product Catalog

Store product details:
redis> HSET product:2000 name "Laptop" price "999.99" stock "50" category "electronics"
(integer) 4
redis> HMGET product:2000 name price
1) "Laptop"
2) "999.99"
redis> HINCRBY product:2000 stock -1
(integer) 49

Statistics Tracking

Track various counters:
redis> HINCRBY stats:website views 1
(integer) 1
redis> HINCRBY stats:website unique_visitors 1
(integer) 1
redis> HINCRBY stats:website page_errors 1
(integer) 1
redis> HGETALL stats:website
1) "views"
2) "1"
3) "unique_visitors"
4) "1"
5) "page_errors"
6) "1"

Rate Limiting by User

Track API calls per endpoint:
redis> HINCRBY rate:user:1000 "/api/users" 1
(integer) 1
redis> HINCRBY rate:user:1000 "/api/posts" 1
(integer) 1
redis> HGET rate:user:1000 "/api/users"
"1"
redis> EXPIRE rate:user:1000 60
(integer) 1

Best Practices

Performance Considerations

  1. Field Access: HGET, HSET are O(1) - very fast
  2. Full Hash: HGETALL is O(N) - use carefully on large hashes
  3. Iteration: Use HSCAN for large hashes instead of HGETALL
  4. Atomic Counters: HINCRBY is atomic and thread-safe

Memory Optimization

  1. Small Hashes: Redis uses efficient ziplist encoding for small hashes
  2. Field Count: Keep under 512 fields for optimal encoding
  3. Value Size: Keep values under 64 bytes for ziplist encoding
  4. Compression: Consider compressing large values before storing

Hash vs Separate Keys

Store related data together:
redis> HSET user:1000 name "Alice" age "30"
(integer) 2
redis> HGET user:1000 name
"Alice"
Pros:
  • Memory efficient for small objects
  • Atomic operations on related data
  • Logical grouping
Cons:
  • Can’t set TTL per field
  • Less flexible for partial updates

Patterns

Object Storage

Store complete objects:
# Store article
redis> HSET article:1 title "Redis Guide" author "alice" views "0" likes "0"
(integer) 4

# Update counters
redis> HINCRBY article:1 views 1
(integer) 1
redis> HINCRBY article:1 likes 1
(integer) 1

Multi-Tenant Counters

Track metrics per tenant:
redis> HINCRBY metrics:tenant1 api_calls 1
(integer) 1
redis> HINCRBY metrics:tenant1 errors 0
(integer) 0
redis> HINCRBY metrics:tenant2 api_calls 1
(integer) 1
redis> HGETALL metrics:tenant1
1) "api_calls"
2) "1"
3) "errors"
4) "0"

Shopping Cart

Store cart items:
# Add items to cart
redis> HSET cart:user:1000 product:1 "2"
(integer) 1
redis> HSET cart:user:1000 product:2 "1"
(integer) 1

# Update quantity
redis> HINCRBY cart:user:1000 product:1 1
(integer) 3

# Get all items
redis> HGETALL cart:user:1000
1) "product:1"
2) "3"
3) "product:2"
4) "1"

# Remove item
redis> HDEL cart:user:1000 product:2
(integer) 1

Feature Flags

Store feature flags per user:
redis> HSET features:user:1000 dark_mode "true" beta_access "false"
(integer) 2
redis> HGET features:user:1000 dark_mode
"true"
redis> HEXISTS features:user:1000 admin_panel
(integer) 0

Configuration Storage

Store application config:
redis> HSET config:app max_connections "100" timeout "30" debug "false"
(integer) 3
redis> HMGET config:app max_connections timeout
1) "100"
2) "30"

Hash vs Other Data Structures

FeatureHashString (JSON)Separate Keys
MemoryEfficientMore overheadMost overhead
Field TTLNoNoYes
Atomic OpsYes (per field)NoYes (per key)
Field AccessO(1)O(N) parseO(1)
Use CaseObjectsComplex dataDistributed data

Advanced Patterns

Lazy Loading

Load hash fields on demand:
# Check if field exists
redis> HEXISTS user:1000 profile_data
(integer) 0

# Load from database and cache
redis> HSET user:1000 profile_data "{...json...}"
(integer) 1

# Next access is from cache
redis> HGET user:1000 profile_data
"{...json...}"

Aggregation

Aggregate metrics from multiple hashes:
# Daily stats
redis> HINCRBY stats:2024-03-03 views 100
(integer) 100
redis> HINCRBY stats:2024-03-03 clicks 25
(integer) 25

# Calculate CTR
redis> HMGET stats:2024-03-03 views clicks
1) "100"
2) "25"
# CTR = 25/100 = 0.25

Batch Updates

Update multiple fields atomically:
redis> HSET order:1000 status "processing" updated_at "1640000000" processor "worker:1"
(integer) 3

Sparse Data

Store only non-null values:
# Only set fields that have values
redis> HSET user:1000 username "alice"
(integer) 1
# Don't set middle_name if not provided
redis> HSET user:1000 last_name "smith"
(integer) 1
Hashes cannot be nested. Each field value must be a string. For complex nested structures, consider storing JSON strings or using multiple hashes.

Common Operations

Check and Set

# Set only if field doesn't exist
redis> HSETNX user:1000 email "[email protected]"
(integer) 1
redis> HSETNX user:1000 email "[email protected]"
(integer) 0

Bulk Retrieval

# Get multiple fields efficiently
redis> HMGET user:1000 username email age
1) "alice"
2) "[email protected]"
3) "30"

Field Counting

redis> HLEN user:1000
(integer) 3

Field Existence

redis> HEXISTS user:1000 username
(integer) 1
redis> HEXISTS user:1000 phone
(integer) 0

Build docs developers (and LLMs) love