A Set in Redis is an unordered collection of unique strings. Adding members with SADD is constant time, \(O(1)\) per element, while reading the full membership list with SMEMBERS is linear in the size of the set, \(O(N)\). For very large sets, this difference matters: SMEMBERS returns the entire collection in a single blocking call, whereas SSCAN iterates incrementally using a cursor and avoids blocking the server. Membership testing is provided by SISMEMBER, which returns 1 if the element is present and 0 otherwise. Set algebra is built in: SUNIONSTORE writes the union of multiple sets into a destination key, and SDIFF returns the members present in the first set but not in any of the others. SRANDMEMBER returns random members without removing them, in contrast to SPOP, which both returns and removes a random element. Typical use cases for sets include tagging items, tracking unique visitors, and powering intersection-based recommendation features.
The Sorted Set, often called a ZSET, extends the set idea by associating a numeric score with each unique member, so that members are kept in order by that score. Internally, Redis implements a sorted set as a combination of a skip list and a hash table, which together give logarithmic insertion and lookup while preserving order. ZADD therefore runs in \(O(\log N)\) time, where N is the number of members. ZREVRANK returns the rank of a member with the highest score at index 0, while ZSCORE returns the score itself, or nil if the member is not in the set. Two range commands are sometimes confused: ZRANGE selects members by their index position, whereas ZRANGEBYSCORE selects members whose score falls in a specified range. ZINCRBY atomically increments a member's score by a given amount, which is useful for scoring events.
Sorted sets lend themselves naturally to use cases such as leaderboards, where members are users and scores are their points; time-series indexes, where scores are timestamps; and rate limiting. A sliding-window rate limiter, for example, can be implemented by storing request timestamps as scores, calling ZREMRANGEBYSCORE to drop entries that have aged out of the window, and then using ZCARD to count how many requests remain inside the window. If the count exceeds the limit, the request is rejected.