Skip to main content
Redis sets are unordered collections of unique strings. They provide O(1) membership testing and efficient set operations like intersection, union, and difference.

Use Cases

  • Tagging systems: Tag articles, products, or users
  • Unique visitors: Track unique IP addresses or user IDs
  • Social graphs: Followers, following, friends lists
  • Voting systems: Track who voted on what
  • Access control: User permissions and roles
  • Random selection: Pick random winners or samples

Key Commands

Basic Operations

# Add members to set
redis> SADD myset "apple" "banana" "cherry"
(integer) 3

# Add duplicate (ignored)
redis> SADD myset "apple"
(integer) 0

# Get all members
redis> SMEMBERS myset
1) "banana"
2) "cherry"
3) "apple"

# Get cardinality
redis> SCARD myset
(integer) 3

# Check membership
redis> SISMEMBER myset "banana"
(integer) 1
redis> SISMEMBER myset "grape"
(integer) 0

Set Operations

# Create two sets
redis> SADD set1 "a" "b" "c" "d"
(integer) 4
redis> SADD set2 "c" "d" "e" "f"
(integer) 4

# Intersection
redis> SINTER set1 set2
1) "c"
2) "d"

# Union
redis> SUNION set1 set2
1) "a"
2) "b"
3) "c"
4) "d"
5) "e"
6) "f"

# Difference
redis> SDIFF set1 set2
1) "a"
2) "b"

# Store result
redis> SINTERSTORE result set1 set2
(integer) 2

Random Operations

# Get random member
redis> SRANDMEMBER myset
"cherry"

# Get multiple random members (with possible duplicates)
redis> SRANDMEMBER myset 3
1) "apple"
2) "banana"
3) "cherry"

# Get unique random members
redis> SRANDMEMBER myset -3
1) "banana"
2) "cherry"
3) "apple"

# Pop random member
redis> SPOP myset
"banana"

Removal

# Remove specific members
redis> SREM myset "apple" "banana"
(integer) 2

# Move member between sets
redis> SMOVE myset otherset "cherry"
(integer) 1

Time Complexity

CommandTime ComplexityDescription
SADDO(1) per memberAdd members
SREMO(N)N=members to remove
SISMEMBERO(1)Check membership
SCARDO(1)Get cardinality
SMEMBERSO(N)N=set cardinality
SINTERO(N*M)N=smallest set, M=sets
SUNIONO(N)N=total members
SDIFFO(N)N=total members
SPOPO(1)Remove random
SRANDMEMBERO(1)Get random

Patterns and Examples

Tagging System

# Add tags to articles
redis> SADD article:123:tags "redis" "database" "nosql"
(integer) 3
redis> SADD article:456:tags "redis" "caching" "performance"
(integer) 3

# Find articles tagged with "redis"
redis> SADD tag:redis:articles "article:123" "article:456"
(integer) 2
redis> SMEMBERS tag:redis:articles
1) "article:123"
2) "article:456"

# Find articles with both "redis" AND "performance"
redis> SINTER tag:redis:articles tag:performance:articles
1) "article:456"

Unique Visitors

# Track unique visitors per day
redis> SADD visitors:2024-03-03 "user:123"
(integer) 1
redis> SADD visitors:2024-03-03 "user:456"
(integer) 1
redis> SADD visitors:2024-03-03 "user:123"
(integer) 0

# Get unique visitor count
redis> SCARD visitors:2024-03-03
(integer) 2

# Find visitors who came back today
redis> SINTER visitors:2024-03-02 visitors:2024-03-03
1) "user:123"

Social Graph - Friend Recommendations

# User's friends
redis> SADD friends:user:123 "user:456" "user:789"
(integer) 2

# Friend's friends
redis> SADD friends:user:456 "user:789" "user:999"
(integer) 2

# Find potential friends (friends of friends, excluding current friends)
redis> SDIFF friends:user:456 friends:user:123
1) "user:999"

Voting System

# Track who upvoted a post
redis> SADD post:123:upvotes "user:456"
(integer) 1
redis> SADD post:123:upvotes "user:789"
(integer) 1

# Check if user already voted
redis> SISMEMBER post:123:upvotes "user:456"
(integer) 1

# Get vote count
redis> SCARD post:123:upvotes
(integer) 2

# Remove vote
redis> SREM post:123:upvotes "user:456"
(integer) 1

Random Winner Selection

# Add contestants
redis> SADD contest:entrants "user:1" "user:2" "user:3" "user:4"
(integer) 4

# Pick a winner (removes from set)
redis> SPOP contest:entrants
"user:3"

# Or pick without removing
redis> SRANDMEMBER contest:entrants
"user:1"

Internal Encoding

Redis uses two encodings for sets:
  • intset: When all members are integers (very memory efficient)
  • hashtable: For string members or large integer sets
redis> SADD intset 1 2 3 4 5
(integer) 5
redis> OBJECT ENCODING intset
"intset"

redis> SADD stringset "a" "b" "c"
(integer) 3
redis> OBJECT ENCODING stringset
"hashtable"
Configuration:
# Max intset entries before converting to hashtable
set-max-intset-entries 512

# Max listpack entries (for small sets)
set-max-listpack-entries 128
set-max-listpack-value 64

Best Practices

  1. Use sets for uniqueness - automatic deduplication
  2. SISMEMBER for lookups - O(1) membership testing
  3. Avoid SMEMBERS on large sets - use SSCAN instead
  4. Use SINTERSTORE/SUNIONSTORE to cache expensive set operations
  5. Consider HyperLogLog for counting unique items with less memory
SMEMBERS returns the entire set. For large sets (over 1000 elements), use SSCAN to iterate incrementally.
For ordered uniqueness (like top contributors), use sorted sets instead of regular sets.

Sets vs Other Types

NeedUseWhy
Uniqueness onlySetsSimple and fast
Uniqueness + orderSorted SetsScore-based ordering
Counting uniquesHyperLogLogMinimal memory
Ordered listListsMaintains insertion order
Key-value pairsHashesStructured data

Next Steps

Set Commands

Complete command reference

Sorted Sets

For ordered unique elements

Build docs developers (and LLMs) love