Set Operations

Sets store unique, unordered members with O(1) add/remove/membership test.

  SADD followers:user:1001 2001 2002 2003
SADD followers:user:1002 2002 2004

SCARD followers:user:1001
SMEMBERS followers:user:1001
SISMEMBER followers:user:1001 2002

# Set algebra — powerful for social and tagging features
SINTER followers:user:1001 followers:user:1002   # mutual followers
SUNION followers:user:1001 followers:user:1002   # all followers
SDIFF followers:user:1001 followers:user:1002    # unique to 1001

# Random sampling
SRANDMEMBER tags:article:42 3
SPOP tags:article:42 1
  

Iterating Large Sets

Never use SMEMBERS on sets with millions of members in production:

  SSCAN followers:user:1001 0 COUNT 100
SSCAN followers:user:1001 1287 COUNT 100   # use returned cursor
  

Sorted Set Rankings

Sorted sets (ZSET) combine unique members with a numeric score for ordering.

  ZADD game:scores 9500 "player_a" 12000 "player_b" 8700 "player_c"

ZREVRANGE game:scores 0 2 WITHSCORES   # top 3 by score
ZRANGE game:scores 0 -1 WITHSCORES       # ascending
ZRANK game:scores "player_a"           # ascending rank (0-based)
ZREVRANK game:scores "player_a"          # descending rank
ZSCORE game:scores "player_b"

# Range by score
ZRANGEBYSCORE game:scores 9000 11000 WITHSCORES
ZCOUNT game:scores 8000 10000
ZREMRANGEBYSCORE game:scores 0 5000      # remove low scores
  

Leaderboard Patterns

  # Increment score atomically
ZINCRBY game:scores 500 "player_a"

# Keep only top 100 players
ZREMRANGEBYRANK game:scores 0 -101

# Leaderboard with timestamps as tiebreaker
ZADD events:timeline 1718200000 "event-uuid-1"
ZADD events:timeline 1718203600 "event-uuid-2"
  

Time-Series with ZSET

Use Unix timestamps as scores for time-ordered data:

  ZADD sensor:temp:room-a 1718200000 "22.5"
ZADD sensor:temp:room-a 1718200060 "22.7"
ZRANGEBYSCORE sensor:temp:room-a 1718199000 1718201000 WITHSCORES
  

Trim old entries periodically with ZREMRANGEBYSCORE.

Streams — Producing Events

Streams are append-only logs with unique IDs and field-value pairs.

  XADD sensor:readings * temp 22.5 humidity 65 location "room-a"
XADD sensor:readings * temp 23.1 humidity 62 location "room-a"
XLEN sensor:readings
XRANGE sensor:readings - + COUNT 10
XREVRANGE sensor:readings + - COUNT 5
  

The * auto-generates IDs: {milliseconds}-{sequence}.

Streams — Consumer Groups

Consumer groups distribute messages across workers with at-least-once delivery.

  # Create group (once)
XGROUP CREATE sensor:readings processors $ MKSTREAM

# Worker reads new messages
XREADGROUP GROUP processors consumer-1 COUNT 10 STREAMS sensor:readings >

# Acknowledge processing
XACK sensor:readings processors 1718200000000-0

# Inspect pending (unacknowledged) messages
XPENDING sensor:readings processors
XCLAIM sensor:readings processors consumer-2 60000 1718200000000-0
  

Pending Message Recovery

Messages remain in the Pending Entry List (PEL) until acknowledged. Use XPENDING and XCLAIM to reassign stale messages from crashed consumers.

  # Trim stream to approximate max length
XTRIM sensor:readings MAXLEN ~ 100000
  

HyperLogLog (Cardinality Estimation)

Estimate unique counts with ~0.81% error using only 12 KB per key.

  PFADD unique:visitors:2024-06-01 user:1001 user:1002 user:1001
PFCOUNT unique:visitors:2024-06-01
# (integer) 2

PFMERGE unique:visitors:week visitors:mon visitors:tue visitors:wed
PFCOUNT unique:visitors:week
  

Use when: UV counts, unique IP tracking — not when exact counts are required.

Bitmap Operations

Treat strings as bit arrays — extremely memory-efficient for boolean flags across millions of IDs.

  SETBIT user:logins:2024-06 15 1    # day 15 login (offset = day number)
GETBIT user:logins:2024-06 15
BITCOUNT user:logins:2024-06

# Daily active users across user IDs
SETBIT dau:2024-06-13 1001 1
SETBIT dau:2024-06-13 1002 1
BITCOUNT dau:2024-06-13
  

Bitwise Operations

  BITOP AND result dau:2024-06-12 dau:2024-06-13   # users active both days
BITOP OR weekly dau:mon dau:tue dau:wed
  

Best Practices

  1. Use SSCAN/ZSCAN instead of full member dumps on large collections
  2. Trim leaderboards with ZREMRANGEBYRANK to cap memory
  3. Always XACK stream messages after successful processing
  4. Monitor PEL size — growing pending lists indicate slow or crashed consumers
  5. Use HyperLogLog for approximate counts; use sets when exact membership matters

Common Mistakes

Mistake Impact
SMEMBERS on million-member sets Blocks server, latency spike
Duplicate stream consumers without unique names Message delivery confusion
Forgetting XACK Messages stuck in PEL, reprocessed forever
ZSET member string collisions Same member, one score — usually intended
HyperLogLog for billing counts Approximate — wrong for financial data

Troubleshooting

Stream consumer lag:

  XINFO GROUPS sensor:readings
XPENDING sensor:readings processors - + 10
# High pending count → scale consumers or fix slow handlers
  

Leaderboard rank wrong after tie scores:

  # Redis orders by score, then lexicographically by member name
ZADD lb 100 "alice" 100 "bob"
ZRANGE lb 0 -1 WITHSCORES
  

Set intersection timeout:

  # SINTER on huge sets is O(N×M) — consider alternative data models
SINTERSTORE temp:mutual k1 k2
SCARD temp:mutual
EXPIRE temp:mutual 60
  

Performance Tips

  • ZREVRANGE top-N is O(log N + M) — efficient for dashboards
  • Batch ZADD via pipelining during bulk score imports
  • Use XREAD BLOCK 5000 for efficient stream polling without tight loops
  • Pre-aggregate with SINTERSTORE/SUNIONSTORE for repeated queries, with TTL on result keys

Production Scenario

A gaming platform maintained global and regional leaderboards using sorted sets. ZREVRANGE served top-100 queries in under 1ms. Stream consumer groups processed 50K match events/minute across 8 workers. HyperLogLog tracked daily unique players (12M DAU) using 144 KB total instead of gigabytes for a full set. Pending message alerts fired when PEL exceeded 10K, catching a deployment bug that stopped acknowledgments.

Sets, sorted sets, and streams unlock social, ranking, and event-driven architectures — the building blocks for real-time applications at scale.