Part 8 · 2 chapters · ~12 min

Patterns

Caching patterns revisited with Redis, distributed locks as leases and the Redlock debate, fencing tokens, rate limiters (fixed window, sliding window, token bucket in Lua), leaderboards with sorted sets, sessions, idempotency key storage, and delayed jobs with sorted sets.

10

Locks and fencing

code
SET lock:recon:2026-10-06 worker-a-7f3c NX PX 30000
-- release only if still owned
if redis.call('GET', KEYS[1]) == ARGV[1] then return redis.call('DEL', KEYS[1]) else return 0 end
A LOCK IN REDIS IS A LEASE
why a paused client can break mutual exclusion, and the fencing token that fixes it
worker ARedisworker BstorageSET lock:recon A NX PX 30000 → OK
swipe the figure sideways, or tap expand for full screen
1/4
acquire
SET key value NX PX 30000 acquires a lock that expires in 30 s, so a crashed holder cannot block forever. Release with a Lua script that deletes only if the value is still yours.
SET NX PX with a unique valuerelease only if still the owner
11

Rate limiters, leaderboards and delayed jobs

code
# fixed window: simple, allows double bursts at window edges
INCR rl:u7:202610061431 ; EXPIRE rl:u7:202610061431 60
# sliding window log with a sorted set: exact, more memory
ZADD rl:u7 <now_ms> <uuid> ; ZREMRANGEBYSCORE rl:u7 0 <now_ms-60000> ; ZCARD rl:u7
# token bucket in Lua: Backend System Design part 2

# leaderboard of agents by monthly volume
ZINCRBY agents:volume:2026-10 1500000 agent:12 ; ZREVRANGE agents:volume:2026-10 0 9 WITHSCORES ; ZREVRANK agents:volume:2026-10 agent:12
# delayed jobs: score = run-at time; a poller moves due items
ZADD delayed <run_at_ms> '{"job":"reminder","id":"t_1"}' ; ZRANGEBYSCORE delayed 0 <now_ms> LIMIT 0 100