Twitter's Real-Time Trending: Redis Sorted Sets in Production
Twitter's trending topics are powered by Redis sorted sets. Every tweet increments the score of its hashtags in a ZADD operation. ZRANGEBYSCORE returns the top trending topics instantly, without any database query. This is not an edge case - Redis sorted sets, pub/sub channels, and HyperLogLog counting are used by Instagram (feed caching), Slack (presence tracking), and GitHub (job queues). Understanding Redis beyond basic GET/SET is what separates junior from senior caching designs.
Redis vs Memcached Decision Matrix
Redis vs Memcached:
Feature Redis Memcached
------------------- ------------------- --------------------
Data structures Strings, Lists, Strings only
Sets, Sorted Sets,
Hashes, Streams
Threading Single-threaded Multi-threaded
(event loop) (better CPU util)
Persistence RDB snapshots + None (pure cache)
AOF append log
Pub/Sub Built-in Not available
Max value size 512 MB 1 MB
Eviction policies 6 options LRU only
Clustering Redis Cluster Consistent hashing
(built-in) (client-side)
Choose Memcached: Simple string caching at max throughput
Choose Redis: You need data structures, pub/sub,
or persistenceWhy Redis Is Single-Threaded (and Why That Is OK)
Redis processes all commands on a single thread using an event loop. This sounds like a limitation, but it is actually a feature: no locks, no race conditions, every command is atomic. A single Redis instance handles 100,000+ operations per second because the bottleneck is network I/O, not CPU. If you need more throughput, Redis Cluster distributes keys across multiple instances. When you do need CPU parallelism, Redis 6+ added I/O threading for network reads and writes while keeping single-threaded command execution.
Essential Redis Patterns
Pattern 1: Sorted Set Leaderboard
ZADD leaderboard 1500 'player1'
ZADD leaderboard 2200 'player2'
ZREVRANGE leaderboard 0 9 WITHSCORES -- top 10
ZRANK leaderboard 'player1' -- rank of player1
Time complexity: O(log N) for all operations
Pattern 2: Atomic Rate Limiter (sliding window)
key = f'rate:{user_id}:{window}'
count = INCR key
if count == 1: EXPIRE key 60 -- set TTL on first request
if count > limit: REJECT
Pattern 3: Distributed Lock (simplified Redlock)
SET lock:resource_42 owner_id NX PX 30000
-- NX = only if not exists
-- PX 30000 = auto-expire in 30 seconds
-- Returns OK (lock acquired) or nil (already locked)
Pattern 4: Pub/Sub for Real-Time Events
SUBSCRIBE chat:room:123 -- listener
PUBLISH chat:room:123 'hello!' -- sender
-- All subscribers receive instantly
Pattern 5: HyperLogLog (unique counting)
PFADD unique_visitors:2024-01-15 'user_42'
PFADD unique_visitors:2024-01-15 'user_99'
PFCOUNT unique_visitors:2024-01-15 -- ~2
-- Uses only 12 KB regardless of cardinality!
-- 0.81% standard error for billions of entriesRedis Persistence: RDB vs AOF
Redis offers two persistence modes. RDB (Redis Database) creates point-in-time snapshots at configurable intervals - fast recovery but you lose data since the last snapshot. AOF (Append Only File) logs every write command - slower recovery but near-zero data loss. Most production deployments use both: AOF for durability (fsync every second for a good balance) and RDB for fast backups and disaster recovery. Cloud-managed Redis services like ElastiCache and Upstash handle replication and persistence automatically, but understanding the modes helps you tune for your durability requirements.
Redis Eviction Policies
When Redis runs out of memory, it evicts keys based on your chosen policy. The most common is allkeys-lru: evict the least recently used key across all keys. For a pure cache layer, this is usually the right choice. If some keys must never be evicted (like sessions), use volatile-lru which only evicts keys that have a TTL set. For sorted sets and leaderboards where newer data matters more, volatile-ttl evicts keys closest to expiration. Choosing the wrong eviction policy can silently break your application - imagine a session cache that evicts active user sessions because it is using allkeys-random instead of volatile-lru.
Interview Tip
Go beyond GET/SET in interviews. Mention sorted sets for leaderboards (O(log N) rank lookups), HyperLogLog for unique counting (12 KB for billions of items), and pub/sub for real-time notifications. When asked 'Redis or Memcached?', the answer is almost always Redis unless you need pure multi-threaded string caching at maximum throughput. Show you understand eviction policies - allkeys-lru is the default choice for most caching workloads.
Key Takeaway
Redis is far more than a key-value cache. Use sorted sets for leaderboards, HyperLogLog for counting unique visitors, pub/sub for real-time events, and distributed locks for resource coordination. Choose RDB+AOF for persistence, allkeys-lru for eviction in cache workloads, and Redis Cluster when a single instance is not enough. Memcached wins only when you need pure string caching with multi-threaded throughput.
