Learning Redis: The Complete Beginner's Guide

Introduction
Redis (Remote Dictionary Server) is an open-source, in-memory data structure store that serves as a database, cache, message broker, and streaming engine. It's one of the most popular tools in modern software development, powering everything from session management to real-time analytics.
Before diving into Redis caching with Spring Boot or any other framework integration, understanding Redis fundamentals is essential. This guide will give you a solid foundation.
What You'll Learn:
✅ What Redis is and why it's so fast
✅ Core data structures (Strings, Lists, Sets, Hashes, Sorted Sets)
✅ Essential Redis commands
✅ Persistence options (RDB vs AOF)
✅ Pub/Sub messaging patterns
✅ Real-world use cases
✅ Best practices for production
Prerequisites:
- Basic command line knowledge
- Docker installed (for running Redis locally)
- Understanding of key-value concepts
Why Redis?
Speed That Matters
Redis stores all data in memory, achieving:
- Sub-millisecond latency for most operations
- 100,000+ operations per second on modest hardware
- Millions of ops/sec with proper configuration
Compare this to traditional databases:
| Operation | PostgreSQL | Redis |
|---|---|---|
| Simple Read | 1-10ms | 0.1-0.5ms |
| Simple Write | 5-20ms | 0.1-0.5ms |
| Complex Query | 10-100ms+ | N/A* |
*Redis doesn't support complex queries - it's optimized for simple, fast operations.
More Than Just a Cache
While caching is Redis's most common use case, it's incredibly versatile:
- Session Store: User sessions with automatic expiration
- Rate Limiter: Track API requests per user/IP
- Leaderboards: Sorted sets for real-time rankings
- Message Queue: Pub/Sub for real-time messaging
- Real-time Analytics: Counters and HyperLogLog for statistics
- Geospatial: Location-based queries and radius searches
Getting Started
Installing Redis with Docker
The easiest way to run Redis locally:
# Run Redis container
docker run -d \
--name redis-local \
-p 6379:6379 \
redis:7-alpine
# Verify it's running
docker ps | grep redis
# Connect to Redis CLI
docker exec -it redis-local redis-cliYou should see the Redis prompt:
127.0.0.1:6379>Your First Commands
Let's start with basic operations:
# Set a key
SET greeting "Hello, Redis!"
# Get a key
GET greeting
# Returns: "Hello, Redis!"
# Check if key exists
EXISTS greeting
# Returns: 1 (true)
# Delete a key
DEL greeting
# Check again
EXISTS greeting
# Returns: 0 (false)Core Data Structures
Redis isn't just a key-value store - it supports rich data structures that enable powerful operations.
1. Strings
The simplest and most versatile data type. Can store text, numbers, or binary data up to 512MB.
# Basic string operations
SET user:1:name "John Doe"
GET user:1:name
# Set with expiration (seconds)
SET session:abc123 "user_data" EX 3600 # Expires in 1 hour
# Set only if key doesn't exist (useful for locks)
SETNX lock:resource "locked"
# Increment/Decrement (atomic operations)
SET counter 0
INCR counter # Returns: 1
INCR counter # Returns: 2
INCRBY counter 10 # Returns: 12
DECR counter # Returns: 11
# Multiple operations
MSET user:1:name "John" user:1:email "john@example.com"
MGET user:1:name user:1:emailUse Cases:
- Caching serialized objects
- Counters and statistics
- Rate limiting
- Distributed locks
2. Lists
Ordered collections of strings. Perfect for queues and recent items.
# Add items to list
LPUSH notifications "New message" # Add to left (head)
RPUSH notifications "Friend request" # Add to right (tail)
# Get list length
LLEN notifications
# Get items by range (0-indexed, -1 means last)
LRANGE notifications 0 -1 # Get all items
LRANGE notifications 0 4 # Get first 5 items
# Pop items (remove and return)
LPOP notifications # Remove from left
RPOP notifications # Remove from right
# Blocking pop (wait for items)
BLPOP queue:jobs 30 # Wait up to 30 seconds for itemUse Cases:
- Message queues (producer/consumer pattern)
- Recent activity feeds
- Undo/redo stacks
- Task queues
3. Sets
Unordered collections of unique strings. Great for membership testing and set operations.
# Add members to set
SADD tags:post:1 "redis" "database" "caching"
# Check membership
SISMEMBER tags:post:1 "redis" # Returns: 1 (true)
SISMEMBER tags:post:1 "python" # Returns: 0 (false)
# Get all members
SMEMBERS tags:post:1
# Set operations
SADD tags:post:2 "redis" "spring" "java"
SINTER tags:post:1 tags:post:2 # Intersection: ["redis"]
SUNION tags:post:1 tags:post:2 # Union: all unique tags
SDIFF tags:post:1 tags:post:2 # Difference: tags in post:1 but not post:2
# Random member
SRANDMEMBER tags:post:1
# Count members
SCARD tags:post:1Use Cases:
- Tags and categories
- Unique visitors tracking
- Friend lists and social connections
- Voting systems (prevent duplicate votes)
4. Hashes
Maps between string fields and values. Perfect for objects.
# Set hash fields
HSET user:1 name "John Doe" email "john@example.com" age 30
# Get single field
HGET user:1 name
# Get multiple fields
HMGET user:1 name email
# Get all fields and values
HGETALL user:1
# Increment numeric field
HINCRBY user:1 age 1 # Now 31
# Check field existence
HEXISTS user:1 email
# Get all field names
HKEYS user:1
# Delete field
HDEL user:1 ageUse Cases:
- User profiles and sessions
- Product details
- Configuration settings
- Object caching (more memory efficient than JSON strings)
5. Sorted Sets
Like sets, but each member has a score for ordering. Incredibly powerful for rankings.
# Add members with scores
ZADD leaderboard 100 "player:1" 85 "player:2" 92 "player:3"
# Get rank (0-indexed, lowest score first)
ZRANK leaderboard "player:1" # Returns position
# Get reverse rank (highest score first)
ZREVRANK leaderboard "player:1"
# Get score
ZSCORE leaderboard "player:1"
# Get range by rank (with scores)
ZRANGE leaderboard 0 2 WITHSCORES # Top 3 (ascending)
ZREVRANGE leaderboard 0 2 WITHSCORES # Top 3 (descending)
# Get range by score
ZRANGEBYSCORE leaderboard 80 95 WITHSCORES
# Increment score
ZINCRBY leaderboard 10 "player:2" # player:2 now has 95
# Count members in score range
ZCOUNT leaderboard 80 100
# Remove members
ZREM leaderboard "player:3"Use Cases:
- Leaderboards and rankings
- Priority queues
- Time-based data (use timestamp as score)
- Rate limiting with sliding windows
Key Expiration and TTL
Redis can automatically expire keys after a specified time - essential for caching.
# Set key with expiration
SET session:token "user_data" EX 3600 # Expires in 3600 seconds
SET session:token "user_data" PX 60000 # Expires in 60000 milliseconds
# Set expiration on existing key
EXPIRE session:token 1800 # 30 minutes from now
EXPIREAT session:token 1735689600 # Unix timestamp
# Check remaining TTL
TTL session:token # Returns seconds, -1 if no expiry, -2 if key doesn't exist
PTTL session:token # Returns milliseconds
# Remove expiration (make persistent)
PERSIST session:tokenBest Practices:
- Always set TTL on cache entries
- Use appropriate TTL based on data volatility
- Consider memory limits when setting long TTLs
- Use
SCANinstead ofKEYS *in production (non-blocking)
Persistence Options
Redis stores data in memory, but offers persistence for durability.
RDB (Redis Database)
Point-in-time snapshots saved to disk.
# Manual snapshot
BGSAVE # Background save
# Configuration (redis.conf)
# save 900 1 # Save if 1 key changed in 900 seconds
# save 300 10 # Save if 10 keys changed in 300 seconds
# save 60 10000 # Save if 10000 keys changed in 60 secondsPros:
- Compact single file
- Fast restarts
- Good for backups
Cons:
- Data loss possible (up to last snapshot)
- Fork can be slow with large datasets
AOF (Append-Only File)
Logs every write operation.
# Configuration (redis.conf)
# appendonly yes
# appendfsync everysec # Sync every second (recommended)
# appendfsync always # Sync on every write (slower but safer)
# appendfsync no # Let OS decide (fastest but risky)Pros:
- More durable (minimal data loss)
- Human-readable log
- Auto-rewrite to compact size
Cons:
- Larger files than RDB
- Slower restarts
Hybrid Approach (Recommended)
Use both RDB and AOF:
# redis.conf
appendonly yes
appendfsync everysec
save 900 1
save 300 10Pub/Sub Messaging
Redis supports publish/subscribe messaging for real-time communication.
# Terminal 1: Subscribe to channel
SUBSCRIBE news:tech
# Terminal 2: Publish message
PUBLISH news:tech "Redis 7.2 released!"
# Pattern subscription
PSUBSCRIBE news:* # Subscribe to all news channels
# Unsubscribe
UNSUBSCRIBE news:techUse Cases:
- Real-time notifications
- Chat applications
- Live updates (sports scores, stock prices)
- Cache invalidation across servers
Limitations:
- No message persistence (missed if subscriber offline)
- No acknowledgment mechanism
- Consider Redis Streams for more robust messaging
Transactions
Redis supports atomic transactions with MULTI/EXEC.
# Start transaction
MULTI
# Queue commands
SET user:1:balance 100
DECRBY user:1:balance 25
INCRBY user:2:balance 25
# Execute all commands atomically
EXEC
# Cancel transaction
DISCARDWatch for Optimistic Locking:
WATCH user:1:balance
val = GET user:1:balance
MULTI
SET user:1:balance (val - 25)
EXEC # Fails if user:1:balance changed since WATCHLua Scripting
For complex atomic operations, use Lua scripts.
# Simple script
EVAL "return redis.call('GET', KEYS[1])" 1 mykey
# Transfer funds atomically
EVAL "
local from = KEYS[1]
local to = KEYS[2]
local amount = tonumber(ARGV[1])
local balance = tonumber(redis.call('GET', from))
if balance >= amount then
redis.call('DECRBY', from, amount)
redis.call('INCRBY', to, amount)
return 1
end
return 0
" 2 user:1:balance user:2:balance 50Benefits:
- Atomic execution
- Reduced network round trips
- Complex logic in single call
Real-World Use Cases
1. Session Management
# Store session
HSET session:abc123 user_id 1 username "john" role "admin"
EXPIRE session:abc123 3600
# Validate session
EXISTS session:abc123
HGET session:abc123 user_id
# Extend session
EXPIRE session:abc123 3600
# Logout
DEL session:abc1232. Rate Limiting
# Simple rate limiter (10 requests per minute)
local key = "ratelimit:" .. user_id
local count = redis.call('INCR', key)
if count == 1 then
redis.call('EXPIRE', key, 60)
end
if count > 10 then
return 0 -- Rate limited
end
return 1 -- Allowed3. Caching with Cache-Aside Pattern
# Check cache first
cached = GET cache:user:1
if cached is nil then
# Cache miss - fetch from database
data = fetch_from_database(1)
# Store in cache with TTL
SET cache:user:1 data EX 300
return data
else
return cached
end4. Real-Time Leaderboard
# Update score on action
ZINCRBY game:leaderboard 10 "player:123"
# Get top 10 players
ZREVRANGE game:leaderboard 0 9 WITHSCORES
# Get player rank
ZREVRANK game:leaderboard "player:123"5. Job Queue
# Producer: Add job
LPUSH jobs:pending '{"type":"email","to":"user@example.com"}'
# Consumer: Process job (blocking)
job = BRPOP jobs:pending 30
# Process job...
# On failure, push to retry queue
LPUSH jobs:retry jobProduction Best Practices
1. Memory Management
# Check memory usage
INFO memory
# Set max memory limit
CONFIG SET maxmemory 2gb
# Set eviction policy
CONFIG SET maxmemory-policy allkeys-lruEviction Policies:
noeviction: Return error when memory limit reachedallkeys-lru: Evict least recently used keysvolatile-lru: Evict LRU keys with TTL setallkeys-random: Random evictionvolatile-ttl: Evict keys with shortest TTL
2. Key Naming Conventions
Use colons to create namespaces:
user:1:profile
user:1:sessions
cache:products:123
queue:emails:pending3. Avoid Anti-Patterns
# ❌ Never use KEYS in production (blocks server)
KEYS user:*
# ✅ Use SCAN instead (cursor-based, non-blocking)
SCAN 0 MATCH user:* COUNT 1004. Connection Pooling
Always use connection pools in your application:
// Spring Boot example
JedisPoolConfig poolConfig = new JedisPoolConfig();
poolConfig.setMaxTotal(128);
poolConfig.setMaxIdle(64);
poolConfig.setMinIdle(16);5. Monitoring
Essential metrics to monitor:
- Memory usage (
used_memory) - Connected clients
- Commands per second
- Cache hit rate
- Keyspace statistics
Summary
Redis is a powerful, versatile tool that every backend developer should know:
Key Takeaways:
✅ Redis is an in-memory data structure store with sub-millisecond latency
✅ Five core data types: Strings, Lists, Sets, Hashes, Sorted Sets
✅ Use TTL for automatic key expiration
✅ Choose persistence based on durability needs (RDB vs AOF)
✅ Pub/Sub enables real-time messaging
✅ Lua scripts for atomic complex operations
✅ Follow best practices for production deployments
Next Steps:
- Practice: Run Redis locally and experiment with commands
- Build: Create a simple rate limiter or session store
- Integrate: Add Redis caching to your application
- Learn More: Explore Redis Streams, Cluster, and Sentinel
Additional Resources
Official Documentation:
Related Tutorials:
- Spring Boot Caching with Redis - Implement Redis caching in Java applications
- Learning Docker: Why It Matters - Containerize your Redis setup
Tools:
- RedisInsight - Official Redis GUI
- redis-cli - Command-line interface
Ready to implement Redis in your applications? Check out Spring Boot Caching with Redis for a complete integration guide!
📬 Subscribe to Newsletter
Get the latest blog posts delivered to your inbox every week. No spam, unsubscribe anytime.
We respect your privacy. Unsubscribe at any time.
💬 Comments
Sign in to leave a comment
We'll never post without your permission.