Redis use cases.
1. Cache layer
def get_user(id):
key = f"user:{id}"
cached = redis.get(key)
if cached: return json.loads(cached)
user = db.user.find(id)
redis.setex(key, 300, json.dumps(user))
return user
2. Session store
sid = secrets.token_urlsafe(32)
redis.setex(f"session:{sid}", 86400 * 7, json.dumps({"user_id": uid}))
3. Rate limiter
def allow(key, limit, window):
pipe = redis.pipeline()
pipe.incr(key); pipe.expire(key, window)
count, _ = pipe.execute()
return count <= limit
4. Queue (Streams)
redis.xadd("jobs", {"task": "process", "id": 42})
# Worker
res = redis.xreadgroup("workers", "w1", {"jobs": ">"}, count=1, block=5000)
Or BullMQ / arq for full lib.
5. Leaderboard
redis.zadd("scores", {"alice": 100, "bob": 85})
top10 = redis.zrevrange("scores", 0, 9, withscores=True)
my_rank = redis.zrevrank("scores", "alice")
6. Real-time feed
# Add post to user's feed
def post(user_id, post_id, ts):
for follower in get_followers(user_id):
redis.lpush(f"feed:{follower}", post_id)
redis.ltrim(f"feed:{follower}", 0, 999) # keep top 1000
def get_feed(user_id, limit=20):
return redis.lrange(f"feed:{user_id}", 0, limit - 1)
Fan-out on write. Or fan-out on read for celebrities.
7. Notifications
redis.lpush(f"notifs:{user_id}", json.dumps(notif))
redis.ltrim(f"notifs:{user_id}", 0, 99)
redis.publish(f"user:{user_id}", json.dumps(notif)) # if user online
8. Presence (online users)
def heartbeat(user_id):
redis.zadd("online", {user_id: time.time()})
def cleanup():
cutoff = time.time() - 60
redis.zremrangebyscore("online", 0, cutoff)
def online_count():
return redis.zcard("online")
Or bitmap by user_id.
9. Counter / analytics
def increment_view(post_id):
redis.incr(f"views:{post_id}")
def daily_views(post_id, date):
return redis.incr(f"views:{date.isoformat()}:{post_id}")
Persist to DB periodically.
10. Distributed lock
token = secrets.token_hex(16)
if redis.set(f"lock:{res}", token, nx=True, ex=30):
try: ...
finally:
# Lua CAS release
...
11. Geofencing
redis.geoadd("drivers", lng, lat, driver_id)
nearby = redis.geosearch("drivers", longitude=user_lng, latitude=user_lat, radius=5, unit="km")
12. AB test bucketing
def variant(user_id, exp):
bucket = redis.hget(f"exp:{exp}", user_id)
if bucket: return bucket
bucket = "A" if hash(f"{exp}:{user_id}") % 2 == 0 else "B"
redis.hset(f"exp:{exp}", user_id, bucket)
return bucket
13. Feature flags
def feature_enabled(feature, user_id):
val = redis.hget(f"feature:{feature}", "config")
config = json.loads(val) if val else {}
if config.get("disabled"): return False
if user_id in config.get("allowlist", []): return True
if user_id in config.get("denylist", []): return False
return user_id % 100 < config.get("percent", 0)
14. Deduplication (Bloom or set)
# Set
if redis.sadd("seen:events", event_id) == 0:
return # duplicate
# Bloom (memory efficient)
if redis.execute_command("BF.EXISTS", "seen", event_id):
return
redis.execute_command("BF.ADD", "seen", event_id)
15. Cursor pagination tokens
def page(after=None, limit=20):
items = redis.zrangebyscore("posts", "(" + (after or "-inf"), "+inf", start=0, num=limit)
next_cursor = items[-1].score if items else None
return items, next_cursor
16. Pub/sub for cache invalidation
def invalidate(key):
redis.delete(key)
redis.publish("invalidations", key)
# Other servers listen and clear local in-memory cache
17. Soft delete with TTL
redis.expire(f"user:{id}", 86400 * 30) # purge after 30 days
18. URL shortener
def shorten(url):
code = base62.encode(redis.incr("counter"))
redis.set(f"url:{code}", url)
return code
19. Trending
# Increment score with decay
redis.zincrby("trending", 1, item_id)
redis.expire("trending", 3600)
top = redis.zrevrange("trending", 0, 9)
20. Inverted index (basic search)
# Index
for word in extract_words(doc):
redis.sadd(f"idx:{word}", doc_id)
# Search
results = redis.sinter([f"idx:{w}" for w in query_words])
For real search: use RediSearch.
Common mistakes
- Using Redis as primary DB for relational data.
- Cache without invalidation strategy.
- Streams without consumer groups for queue.
- Lists growing unbounded (no LTRIM).
- Forgetting persistence when treating it as a queue.
Read this next
If you want my Redis recipes library, it’s at rajpoot.dev .
Building something AI-, backend-, or data-heavy and want a second pair of eyes? I do consulting and freelance work — see my projects and ways to reach me at rajpoot.dev .