Sets
Redis sets are unordered collections of unique strings. SADD / SREM / SISMEMBER are O(1); union / intersect / diff are atomic, fast, and the foundation of tag systems, dedup, and follower graphs.
SADD, intersections, unions, real recipes
EXAMPLE
# 1) Basic operations
SADD tags red blue green # add 3 members; returns 3 added
SADD tags red # returns 0 (already there)
SCARD tags # count
SISMEMBER tags blue # 1 (member) / 0 (not)
SMISMEMBER tags blue purple # batch check
SREM tags red # remove
SMEMBERS tags # all members
SRANDMEMBER tags # random member
SRANDMEMBER tags 3 # 3 random distinct
SPOP tags # pop random member (removes it)
# 2) Set arithmetic
SADD a 1 2 3 4
SADD b 3 4 5 6
SINTER a b # intersection: 3 4
SUNION a b # union: 1 2 3 4 5 6
SDIFF a b # in a not in b: 1 2
# Store the result
SINTERSTORE common a b # → common = {3, 4}
SUNIONSTORE all a b # → all = {1..6}
SDIFFSTORE only_a a b # → only_a = {1, 2}
# 3) Scan to iterate without blocking (large sets)
SSCAN tags 0 MATCH * COUNT 100
# === Real recipes ===
# 4) Unique visitor count per day (cheaper than COUNT(DISTINCT) in DB)
SADD visitors:2026-06-08 user_42
SADD visitors:2026-06-08 user_99
SCARD visitors:2026-06-08 # unique visitors today
# 7-day unique visitors (union of 7 daily sets)
SUNIONSTORE visitors:last7 visitors:2026-06-02 visitors:2026-06-03 ... visitors:2026-06-08
SCARD visitors:last7
# (For massive cardinalities, use HyperLogLog — PFADD / PFCOUNT)
# 5) Tag system — bidirectional
SADD post:42:tags python redis backend
SADD tag:python:posts 42 51 67
SADD tag:redis:posts 42 18 91
# Posts tagged with BOTH python AND redis:
SINTER tag:python:posts tag:redis:posts
# Posts tagged with python OR redis:
SUNION tag:python:posts tag:redis:posts
# 6) Social — follower / following graph
SADD user:42:following user:99 user:51
SADD user:99:followers user:42
SADD user:51:followers user:42
# 'People you may know' = friends of friends, minus already-following
SINTER user:42:following user:99:following # users you both follow
SDIFF user:99:following user:42:following user:42 # who 99 follows that you don't
# 7) Online users / presence
SADD online:room:42 user:99
SADD online:room:42 user:51
EXPIRE online:room:42 30 # auto-cleanup after 30s
# Active rooms
SCARD online:room:42
# 8) Permission / role system
SADD role:admin:perms can_delete can_ban can_edit
SADD role:editor:perms can_edit
# Does this user have permission?
SADD user:42:perms can_edit
SISMEMBER user:42:perms can_delete # 0 — no
# 9) Rate limit lists (allowlist / denylist)
SADD allowed_ips 10.0.0.5 10.0.0.7
SADD blocked_ips 203.0.113.42
SISMEMBER blocked_ips $client_ip
# 10) Job dedup
# Before queuing a job, check if it's already queued:
SISMEMBER queued_jobs job:hash:abc
# If not, add to set + push to a list
SADD queued_jobs job:hash:abc
LPUSH queue:jobs job:abc
# After processing, SREM the job hash.
# 11) Node + ioredis
import Redis from 'ioredis';
const redis = new Redis();
await redis.sadd('visitors:today', userId);
const unique = await redis.scard('visitors:today');
const tagged = await redis.sinter('tag:python:posts', 'tag:redis:posts');
# Conditional follow (atomic — only add if not already present, return delta)
const added = await redis.sadd(`user:${a}:following`, b);
if (added) {
await redis.sadd(`user:${b}:followers`, a);
await bus.publish('follow', { a, b });
}
# 12) Performance
# - SADD / SREM / SISMEMBER are O(1)
# - SINTER is O(N*M) where N is smallest set, M is number of sets — keep small sets first
# - SMEMBERS is O(N) — avoid on huge sets; use SSCAN
# - Use SPOP for unique sampling without replacement
# 13) Set vs sorted set vs hash
# Set : unique members, no order, set arithmetic
# Sorted set : unique members WITH a score (leaderboards, time windows)
# Hash : key → value within one Redis key (object field updates)
# List : ordered, allows duplicates (queues, recent-N)
# 14) Use cases at a glance
# Unique counts (low cardinality) — Set + SCARD
# Unique counts (huge cardinality) — HyperLogLog (PFADD / PFCOUNT)
# Tag systems / many-to-many — Sets on both sides
# Followers / friends-of-friends — Set intersection / difference
# Online users with TTL — Set + EXPIRE on the key
# Permissions — Set + SISMEMBER
# 15) Common pitfalls
# • SMEMBERS on a million-element set blocks Redis — use SSCAN
# • Forgetting EXPIRE — sets grow forever
# • Storing big JSON blobs as set members — keep members as IDs
Why it matters
Sets turn set theory into one-line Redis operations — tag systems, mutual-followers, online users, unique daily visitors. For massive cardinalities (millions of unique IPs), switch to HyperLogLog and trade ~0.8% error for kilobytes of memory.
Tip: Tweak the snippet with Try it Yourself », then sit the quiz at the bottom of the page.
Example
Example
SADD tags "sql" "postgres" "redis" SMEMBERS tags SISMEMBER tags "sql" # 1 SINTER tagsA tagsB # intersectionTry it Yourself »
Discussion
Loading…