By now the pattern of Redis should be clear: its real power is that common, otherwise-awkward problems map directly onto its data structures, turning subsystems into a few commands. This lesson collects the best of those patterns — leaderboards, rate limiting, unique-counting at scale, bitmaps and geospatial — each one a small amount of Redis doing what would be a real engineering effort elsewhere.
The patterns
Leaderboards (sorted sets)
The showcase use of sorted sets (Lesson 2). A leaderboard is a sorted set where the score is the ranking value:
ZADD leaderboard 4820 "player:7"— set or update a player’s score (O(log n)).ZREVRANGE leaderboard 0 9 WITHSCORES— the top 10, instantly.ZREVRANK leaderboard "player:7"— a player’s rank (their position), in O(log n).ZRANGEBYSCORE/ZREVRANGEBYSCORE— players within a score band (“ranks 100–110 around me”).
Real-time rankings over millions of players, updated and queried in O(log n). The same thing in a relational database means an ORDER BY ... LIMIT (and an expensive rank computation) on every read — slow and load-heavy. In Redis it’s a built-in. This pattern extends to anything “ranked by a number”: trending items (score = recent activity), priority queues (score = priority), time-ordered feeds (score = timestamp).
Rate limiting
The classic Redis coordination job (Lesson 10), done a few ways depending on precision:
- Fixed window —
INCR rate:user:42:<minute>, reject if over the limit,EXPIREso it resets. Simple; has edge bursts at window boundaries. - Sliding window — a sorted set of request timestamps per user: add the current timestamp, remove ones older than the window, count what’s left. Smooth, precise, slightly more work.
- Token bucket — a Lua script tracking tokens and refill rate, one atomic operation per request. The most flexible (allows bursts up to a cap with a steady refill).
All are atomic, fast, per-user, and run entirely in Redis — no database round trips on the hot path.
Counting uniques at scale (HyperLogLog)
Counting unique things — unique visitors, unique search terms — normally means storing every distinct id (a set), which costs memory proportional to the cardinality: millions of uniques = lots of RAM. HyperLogLog is a probabilistic structure that estimates the unique count in a fixed ~12 KB, regardless of how many uniques there are, with about 0.8% error:
PFADD visitors:2026-10-30 user:42 user:99 ...— add elements.PFCOUNT visitors:2026-10-30— estimate the unique count (~0.8% error).PFMERGE— combine HLLs (e.g. daily into monthly).
So you can count millions of unique visitors across many days using kilobytes, not gigabytes — trading a tiny, bounded error for enormous memory savings. When you need an approximate unique count at scale (and you almost always can tolerate 0.8% error for analytics), HyperLogLog is the tool.
Bitmaps and geospatial
Two more structures that solve specific problems compactly:
- Bitmaps — a string treated as an array of bits (
SETBIT/GETBIT/BITCOUNT). Track daily-active-users by setting bit N when user N is active today;BITCOUNTgives the active count, andBITOPcombines days (users active on day A and B). A million users is ~125 KB (one bit each) — astonishingly compact for presence/activity tracking. - Geospatial —
GEOADDstores locations (lat/long) in a sorted set (encoded as geohashes), andGEOSEARCHanswers ”what’s within 2 km of this point?” sorted by distance. “Shops near me,” “drivers near the rider” — a few commands instead of a spatial database.
The theme: structures, not bolt-ons
The unifying point is that none of these are special features bolted onto Redis — they fall out of the core data structures and the single-threaded atomicity:
- A leaderboard is literally a sorted set.
- A unique-count is a HyperLogLog (or a set).
- A rate limiter is a counter or sorted set with atomic operations.
- Active-user tracking is a bitmap; “near me” is a geospatial sorted set.
So the way to find the right Redis solution is always the same question from Lesson 2: which structure does this problem map onto? When it maps cleanly, the implementation is a handful of O(1)/O(log n) commands — atomic, fast, in-memory — rather than a batch job or a specialised system. That mapping is the real skill of using Redis well, and it’s why Redis shows up in so many systems doing so many different jobs. The final lesson brings it back to operating all this safely in production.
Pitfalls to Avoid
- Building a leaderboard outside Redis. Sorting in the app or an
ORDER BYon every read is slow and load-heavy. A sorted set gives O(log n) updates, top-N and rank built in. Use it. - Storing every id to count uniques at scale. A set of millions of ids burns RAM. If ~0.8% error is acceptable (it usually is for analytics), use HyperLogLog — fixed ~12 KB for any cardinality.
- Using HyperLogLog when you need exact counts or the members. HLL is an estimate and can’t list its members. For exact counts or membership, use a set (and accept the memory).
- Fixed-window rate limits where boundary bursts matter. A fixed window allows up to 2× the limit across a boundary. If that matters, use a sliding window or token bucket.
- Ignoring the memory of the structure. A giant sorted set (leaderboard with tens of millions of entries) or bitmap still costs memory and can be a big key (Lesson 12). Cap, shard, or expire where appropriate.
- Reaching for a specialised system prematurely. “Near me” doesn’t always need a spatial database; a unique count doesn’t always need a data-warehouse query. If it maps to a Redis structure and the scale fits, Redis is simpler.
Quick Recap
- Leaderboards = sorted sets:
ZADD/ZREVRANGE(top-N) /ZREVRANK(rank), all O(log n) — real-time rankings that are painful in a relational DB. - Rate limiting:
INCR+EXPIRE(fixed window), a sorted set (sliding window), or a Lua token bucket — atomic, per-user, no DB round trip. - HyperLogLog: estimate unique counts in ~12 KB for any cardinality (~0.8% error) — millions of uniques without storing every id (
PFADD/PFCOUNT/PFMERGE). - Bitmaps (
SETBIT/BITCOUNT) track active users as bits (tiny); geospatial (GEOADD/GEOSEARCH) answers “within X km”. - The theme: these fall out of the data structures — map the problem to a structure, and the solution is a few O(1)/O(log n) commands.
Next lesson, the last: running all this safely — operating Redis and the pitfalls (big keys, slow commands, when NOT to use it).