Redis Hashes
Hashes are maps between string fields and string values—perfect for representing objects. They're memory-efficient when storing many small key-value pairs and provide O(1) access to individual fields.
Key Characteristics
• Can store up to 4 billion field-value pairs • Memory-optimized for small hashes (ziplist encoding) • Supports partial updates without reading/writing entire object • Ideal for user profiles, product details, configuration objects
Basic Operations
# Set and get fields
HSET user:1000 name "Alice" email "alice@example.com" age 28
HGET user:1000 name # Get single field → "Alice"
HMGET user:1000 name email # Get multiple fields
HGETALL user:1000 # Get all field-value pairs
# Check field count
HLEN user:1000 # Number of fields → 3Incrementing Numeric Fields
Hash fields can store integers and floats that Redis can increment atomically.
HSET user:1000 age 28 balance 100.50
HINCRBY user:1000 age 1 # Increment age → 29
HINCRBY user:1000 age -5 # Decrement age → 24
HINCRBYFLOAT user:1000 balance 99.50 # Add to balance → 200.00
HINCRBYFLOAT user:1000 balance -50.25 # Subtract → 149.75Field Existence and Deletion
HEXISTS user:1000 phone # Check if field exists → 0
HSETNX user:1000 phone "555-1234" # Set only if field doesn't exist
HDEL user:1000 phone # Delete field
HDEL user:1000 field1 field2 field3 # Delete multiple fieldsMetadata Operations
HKEYS user:1000 # Get all field names
HVALS user:1000 # Get all values
HLEN user:1000 # Count of fields → 3
HSTRLEN user:1000 name # Length of field valueScanning Large Hashes
Use HSCAN for non-blocking iteration over large hashes.
# Iterate with cursor (non-blocking)
HSCAN user:1000 0 COUNT 10 # Start from cursor 0
HSCAN user:1000 17 COUNT 10 # Continue from returned cursor
HSCAN user:1000 0 MATCH email* COUNT 10 # Filter by patternUse Case: User Profiles
Store user attributes with granular field updates.
# Create user profile
HSET user:1000
username "alice"
email "alice@example.com"
created_at "2024-01-15"
login_count 0
premium false
# Update specific fields without touching others
HINCRBY user:1000 login_count 1
HSET user:1000 last_login "2024-01-16T10:30:00Z"
HSET user:1000 premium true
# Get profile
HGETALL user:1000Use Case: Shopping Cart
Product IDs as fields, quantities as values.
cart_key = "cart:user:123"
# Add items
HSET cart_key "product:abc" 2 # 2x Product ABC
HSET cart_key "product:xyz" 1 # 1x Product XYZ
# Update quantity
HINCRBY cart_key "product:abc" 1 # Add one more → 3
HINCRBY cart_key "product:abc" -1 # Remove one → 2
# Remove item
HDEL cart_key "product:xyz"
# Get cart contents
HGETALL cart_key
# Clear cart
DEL cart_keyUse Case: Daily Statistics
Multiple counters under one key, organized by date.
stats_key = "stats:page:home"
# Increment daily views
HINCRBY stats_key "2024-01-15" 1
HINCRBY stats_key "2024-01-16" 1
HINCRBY stats_key "2024-01-16" 1
# Get all daily counts
HGETALL stats_key
# Returns: {"2024-01-15": "1", "2024-01-16": "2"}
# Get specific day
HGET stats_key "2024-01-16"Memory Efficiency
Hashes use ziplist encoding when small, which is very memory-efficient. Configure thresholds in redis.conf:
# redis.conf settings
hash-max-ziplist-entries 512 # Max fields for ziplist
hash-max-ziplist-value 64 # Max field/value size for ziplist
# Check encoding
OBJECT ENCODING user:1000 # → "ziplist" or "hashtable"
MEMORY USAGE user:1000 # Bytes used by key