Skip to content

Redis Sets and Set Operations

Aman Kumar Singh4 min read
Part 6 of 15From the Redis Masterclass series
Redis Sets and Set Operations — article by Aman Kumar Singh

A Redis set is an unordered collection of unique strings. Two things make it valuable: membership tests are instant, and Redis can compute intersections, unions, and differences between sets inside the database. That turns questions like "is this user following that one," "what tags do these two articles share," and "how many unique visitors today" into single fast commands, instead of loops in your application code.

This is part 6 of the Redis Masterclass, following lists and queues.

The basics: unique membership

A set stores unique values and tells you fast whether something is in it:

SADD article:1:tags "redis" "database" "caching"
SADD article:1:tags "redis"        # ignored, already present
SISMEMBER article:1:tags "redis"   # 1 (yes), O(1)
SCARD article:1:tags               # 3 (count of members)
SMEMBERS article:1:tags            # all members
SREM article:1:tags "caching"      # remove a member

The uniqueness is automatic: adding a value that's already there is a no-op. And SISMEMBER is constant-time, so a set is the right structure whenever you need to ask "is X in this group" quickly: a user's permissions, blocked ids, IPs already seen, tags on an item. Storing those as a set gives you instant membership checks that a list or a database query can't match.

Set algebra in the database

The feature that sets sets apart is computing relationships between them. Three operations, each done atomically in Redis:

SINTER user:1:follows user:2:follows   # accounts both follow (mutual)
SUNION article:1:tags article:2:tags   # all tags across both
SDIFF user:1:follows user:2:follows    # who user 1 follows that user 2 doesn't

These replace application-side loops. Finding mutual follows without Redis means loading both follow lists and intersecting them in code; with a set it's one SINTER. The STORE variants (SINTERSTORE, SUNIONSTORE) write the result to a new set, useful for caching a computed relationship. Because the work happens in Redis over its in-memory sets, it's fast even for large collections.

Real uses

The pattern shows up all over:

  • Tags and categories: an item's tags as a set, then SINTER to find items sharing tags, or SismEMBER to check a tag.
  • Relationships: followers, friends, group members. Mutual connections are SINTER, "people you follow who follow them" is set math.
  • Access control: a user's permission set, checked with SISMEMBER on each request.
  • Deduplication: add ids to a set as you process them and SADD returns whether the value was new, so you skip already-seen items for free.
  • Unique tracking: unique visitors or unique actions per day, since a set only counts each value once.

That last use has a scaling caveat worth flagging: a set of unique visitor ids grows with the number of visitors, which for a large site means a lot of memory. When you only need the approximate count, not the actual members, HyperLogLog does it in tiny fixed memory, which we'll cover later. Use a real set when you need the members or exact counts, HyperLogLog when you only need an approximate cardinality.

Random members and use as a pool

Sets have handy operations for picking members:

SRANDMEMBER quiz:questions 5   # 5 random members, without removing
SPOP raffle:entries            # remove and return a random member

SRANDMEMBER is useful for sampling (random questions, a random subset), and SPOP for consuming from a pool without order, like drawing a raffle winner or handing out unique tokens. The randomness plus uniqueness makes sets a clean fit for "pick some distinct items" needs.

Sets vs other structures

To place sets among the options:

  • Need uniqueness and membership tests, or set math (intersection, union, difference): a set.
  • Need the members ordered or ranked: a sorted set (next article), which adds a score.
  • Need duplicates or insertion order: a list.
  • Need only an approximate unique count at scale: HyperLogLog, not a set.

Sets are the tool for unique collections and relationships. Instant membership checks and in-database set algebra turn a category of "load data and loop in the app" problems into single commands. When your question is "is it in the group" or "what's shared between these groups," a set answers it directly and fast.

Next, we cover sorted sets, which add a score to each member and unlock leaderboards, priority queues, and time-ordered data, the most versatile structure Redis has.

Key takeaways

  • A Redis set holds unique values with automatic deduplication and constant-time membership tests via `SISMEMBER`.
  • `SINTER`, `SUNION`, and `SDIFF` compute intersections, unions, and differences in the database, replacing application-side loops.
  • Sets fit tags, relationships (mutual follows), access control, deduplication, and unique tracking.
  • A set of unique ids grows with cardinality; use HyperLogLog when you only need an approximate unique count at scale.
  • `SRANDMEMBER` and `SPOP` sample or consume random members, useful for pools and raffles.

Frequently asked questions

What is a Redis set used for?

Storing unique values with fast membership checks and computing relationships between collections. Common uses include tags, follower/friend relationships, permission sets, deduplication, and tracking unique items.

How do I find common elements between two sets?

Use `SINTER key1 key2`, which returns the intersection (members in both) atomically. For example, `SINTER user:1:follows user:2:follows` gives the accounts both users follow. `SUNION` and `SDIFF` give union and difference.

How is a set different from a list in Redis?

A set is unordered, stores only unique values, and offers fast membership tests and set algebra. A list is ordered, allows duplicates, and is suited to queues and sequences. Choose a set for uniqueness and membership, a list for order.

How do I count unique visitors with Redis?

Add each visitor id to a set and read `SCARD` for the exact count. If you only need an approximate count and the id set would be huge, use HyperLogLog instead, which estimates cardinality in tiny fixed memory.

How do I pick random items from a set?

Use `SRANDMEMBER key count` to get random members without removing them, or `SPOP key` to remove and return a random member. These suit sampling and consuming from an unordered pool like a raffle.

Related articles

Redis Hashes: Storing Objects — Aman Kumar Singh
Redis Data Structures: An Overview — Aman Kumar Singh
Redis Caching Best Practices and Pitfalls — Aman Kumar Singh
Aman Kumar Singh

About the author

I'm Aman Kumar Singh, a software engineer in Noida, India building scalable full-stack products with React, Next.js, Node.js, NestJS, PostgreSQL, Redis, and AWS. I write about backend engineering, distributed systems, and system design.