Redis is an open-source, in-memory data structure store, used as a database, cache, and message broker. Current stable release is Redis 7.2.x, with 7.4.x in release candidate as of late 2025.
Core Syntax
Basic key-value operations for strings, the simplest data type.
SET user:1:name "Alice" EX 3600 NX // Set key 'user:1:name' to "Alice", expire in 3600 seconds, only if key does NOT exist.
GET user:1:name // Retrieve the value associated with 'user:1:name'.
DEL user:1:name // Delete the key 'user:1:name'.
INCR page:views // Increment the integer value of 'page:views' by one. Creates key with 0 if non-existent.
DECRBY product:stock 5 // Decrement the integer value of 'product:stock' by five.
Essential Patterns
Redis offers diverse data structures. Leverage them for efficient data modeling beyond simple strings.
Hashes: Storing Objects
Represent objects with multiple fields.
HSET user:2 id 2 name "Bob" email "bob@example.com" // Set multiple fields for hash 'user:2'.
HGET user:2 name // Retrieve a single field 'name' from hash 'user:2'.
HGETALL user:2 // Retrieve all fields and values from hash 'user:2'.
HDEL user:2 email // Delete the 'email' field from hash 'user:2'.
Lists: Ordered Collections
Implement queues, stacks, or capped collections.
LPUSH tasks:queue "task_A" "task_B" // Push elements to the left (head) of 'tasks:queue'.
RPUSH logs:stream "log_entry_1" // Push elements to the right (tail) of 'logs:stream'.
LPOP tasks:queue // Remove and return the first element from 'tasks:queue'.
RPOP logs:stream // Remove and return the last element from 'logs:stream'.
LRANGE logs:stream 0 -1 // Get all elements from 'logs:stream' (from index 0 to last).
LTRIM logs:stream 0 99 // Keep only the first 100 elements in 'logs:stream', effectively capping it.
Sets: Unique, Unordered Collections
Ideal for tracking unique items or relationships.
SADD users:online "user_X" "user_Y" // Add members to the set 'users:online'. Duplicates are ignored.
SMEMBERS users:online // Get all members of 'users:online'.
SISMEMBER users:online "user_X" // Check if "user_X" is a member of 'users:online'. Returns 1 or 0.
SREM users:online "user_Y" // Remove "user_Y" from 'users:online'.
SINTER users:online users:premium // Get members common to both sets.
Sorted Sets: Ordered Unique Collections
Store members with scores, enabling ranking and range queries.
ZADD leaderboard 100 "player_A" 200 "player_B" 150 "player_C" // Add members with scores to 'leaderboard'.
ZSCORE leaderboard "player_B" // Get the score of "player_B".
ZRANGE leaderboard 0 -1 WITHSCORES // Get all members and their scores, ordered by score ascending.
ZREVRANGE leaderboard 0 9 BYSCORE WITHSCORES // Get top 10 members by score descending.
ZINCRBY leaderboard 50 "player_A" // Increment "player_A"'s score by 50.
Common Use Cases
Redis excels in specific application patterns due to its speed and data structures.
Caching Layer
Store frequently accessed data to reduce database load.
// Application logic:
// 1. Try to GET product:123 from Redis.
// 2. If not found, fetch from primary DB.
// 3. SET product:123 with data, and an appropriate expiration.
SET product:123 '{"id":123,"name":"Widget","price":19.99}' EX 300 // Cache product data for 5 minutes.
GET product:123 // Retrieve cached product data.
Rate Limiting
Implement request throttling using INCR and EXPIRE.
// Example: Allow 10 requests per user per minute.
// Key: 'rate_limit:user:{userId}:{timestamp_minute}'
INCR user:123:req:202512301030 // Increment request count for user 123 in current minute.
EXPIRE user:123:req:202512301030 60 // Set expiration for 60 seconds (if not already set).
GET user:123:req:202512301030 // Check current request count. If > 10, deny request.
Publish/Subscribe Messaging
Decouple services with real-time message broadcasting.
// Terminal 1 (Subscriber):
SUBSCRIBE chat:room:general // Subscribe to messages on 'chat:room:general'.
// Terminal 2 (Publisher):
PUBLISH chat:room:general "Hello everyone!" // Publish a message to 'chat:room:general'.
PUBLISH chat:room:general "New message here." // Another message.
Gotchas & Best Practices
Avoid common pitfalls and ensure optimal Redis performance and stability.
Avoid KEYS * in Production
KEYS * is a blocking command and can severely impact performance on large datasets. Use SCAN for production.
// BAD: Blocks Redis for potentially long periods.
KEYS *
// GOOD: Iterates incrementally, non-blocking. Returns cursor and batch of keys.
SCAN 0 MATCH user:* COUNT 100 // Start scan from cursor 0, match 'user:*', return up to 100 keys.
// ... repeat with new cursor until 0 is returned.
Set Expiration (TTL) for Temporary Data
Prevent memory exhaustion by always setting EXPIRE for cache entries and temporary session data.
SET session:user:456 "token_abc" EX 1800 // Store session token for 30 minutes.
TTL session:user:456 // Check remaining time-to-live for the key.
PERSIST session:user:456 // Remove expiration from the key.
Configure maxmemory and Eviction Policy
Essential for managing memory usage, especially when Redis is used as a cache.
// In redis.conf or using CONFIG SET
CONFIG SET maxmemory 2gb // Limit Redis memory usage to 2GB.
CONFIG SET maxmemory-policy allkeys-lru // Evict least recently used keys when maxmemory is reached.
// Other policies: volatile-lru, allkeys-random, volatile-ttl, noeviction, etc.
Advanced Techniques
Unlock more powerful Redis capabilities for complex scenarios.
Transactions (MULTI/EXEC)
Ensure atomicity for a sequence of commands. All commands are executed in order, or none.
MULTI // Start a transaction block.
INCR user:1:balance // Command 1: Increment balance.
LPUSH audit:log "user:1 balance updated" // Command 2: Log the update.
EXEC // Execute all queued commands atomically.
// If WATCH was used, EXEC will fail if watched keys changed.
Lua Scripting
Execute complex, atomic operations directly on the Redis server, reducing network round-trips.
// Script to atomically increment a counter and set an expiry if it's the first increment.
EVAL "local current = redis.call('INCR', KEYS[1]); if current == 1 then redis.call('EXPIRE', KEYS[1], ARGV[1]); end; return current;" 1 my_counter 60
// KEYS[1] is 'my_counter', ARGV[1] is '60'.
// This script ensures that EXPIRE is set only once when the counter is initialized to 1.
Streams
A powerful, append-only data structure for immutable log-like data, enabling consumer groups.
XADD mystream * sensor_id 123 temperature 25.5 // Add an entry to 'mystream', '*' auto-generates ID.
XREAD COUNT 2 STREAMS mystream 0 // Read 2 entries from 'mystream' starting from ID 0.
XGROUP CREATE mystream mygroup $ MKSTREAM // Create consumer group 'mygroup' for 'mystream', starting from latest entry.
XREADGROUP GROUP mygroup consumer1 COUNT 1 STREAMS mystream > // Consumer 'consumer1' reads 1 new entry from 'mygroup'.
XACK mystream mygroup 1678881234567-0 // Acknowledge processing of entry ID 1678881234567-0.
Quick Reference
- Data Types: Strings, Hashes, Lists, Sets, Sorted Sets, Streams, Geospatial, Bitmaps, HyperLogLogs.
- Persistence: RDB (snapshotting), AOF (append-only file). Both can be enabled.
- High Availability: Redis Sentinel (for automatic failover), Redis Cluster (for sharding and HA).
- Transactions:
MULTI,EXEC,DISCARD,WATCH. - Lua Scripting:
EVAL,EVALSHA. Atomic execution. - Memory Management:
maxmemory,maxmemory-policy. Crucial for cache use. - Monitoring:
INFO,MONITOR,CLIENT LIST. - Security: Bind to specific IPs, enable
requirepass, use TLS (Redis 6+).
References
This page is AI-assisted. References official documentation.