In revision.
Crisp5 min readGo deeper →

Redis

Why I used Redis at Binocs for caching, rate limiting, and pub/sub, and when I would not reach for it.

Redis is single-threaded in-memory key-value store with optional disk persistence. That single sentence is most of what you need. The reason it shows up on every resume is that the data structures are exactly the ones distributed systems need: strings, hashes, lists, sets, sorted sets, streams, hyperloglogs.

Where I used it at Binocs

Three jobs:

  1. Caching expensive Postgres reads. A compliance check that took 800ms in Postgres took 2ms from Redis. TTL of 5 minutes, invalidated on write.
  2. Rate limiting per tenant. Sorted set keyed by tenant ID, score is the request timestamp, count members in the last 60 seconds, reject if over the limit.
  3. Pub/sub for cross-service notifications. When a webhook arrived, we published to a channel and three downstream workers picked it up.

The mental model

Redis is a single thread serving commands from a queue, plus an event loop for I/O. Commands are atomic by definition because nothing else runs while yours does. This is why INCR, LPUSH, and ZADD are safe to call from a hundred clients without locks.

Single-threaded also means one slow command blocks everything. KEYS * on a million keys will freeze your cluster. Use SCAN instead. Same with FLUSHDB and big LRANGE 0 -1 calls.

Persistence options

  • RDB: periodic snapshot to disk. Fast restart, but you lose anything since the last snapshot.
  • AOF: append every write to a log. More durable, slower, file grows large.
  • Both: snapshot + tail of the AOF. What we ran in production.

If durability matters, you need AOF with appendfsync everysec at minimum. Even then, the last second of writes can be lost on a crash. Redis is not Postgres.

When I would not use it

  • As a queue if you need at-least-once delivery semantics. Use SQS, Kafka, or Redis Streams with consumer groups, not plain pub/sub.
  • For data that cannot be recomputed. RAM is expensive and a node failure with bad persistence config means data loss.
  • For very large values. Storing 10 MB blobs in Redis works but defeats the latency advantage and blows up your memory.

Learn more