Redis is an in-memory data structure server: clients send short commands over TCP, and Redis applies them to strings, hashes, lists, sets, sorted sets, streams and a few specialised types held in RAM. One thread executes the commands one at a time, so each command and each script is atomic, and most finish in well under a millisecond. It is the default interview pick for caches, counters, rate limits, leaderboards, sessions and short-lived locks, and the wrong pick for data that must never lose an acknowledged write.
This page tracks Redis Open Source 8.x (8.10, July 2026, is the current stable line); the core guarantees are unchanged since Redis 7 and apply equally to the Valkey fork.
Picture it first
Picture a station enquiry counter run by one very fast clerk with a huge whiteboard: seats left on the 12951, the platform for the 6:15 local. The clerk serves one person at a time, but each answer takes a second, so the queue moves. Because nobody else touches the board mid-answer, “reduce seats left by one” happens completely or not at all.
A power cut would wipe the board, so every few minutes someone photographs it, and the clerk jots each change in a diary that goes into the safe once a second. An assistant at the next counter copies the board by listening to the clerk, usually a moment behind. On festival days the station opens three counters and splits passengers by PNR number.
Map it back:
- Clerk → the main thread: one command at a time, so each is atomic.
- Whiteboard → RAM: fast, finite and lost on a crash. When it is full, something gets erased (eviction).
- Photo → an RDB snapshot; diary → the append-only file (AOF) with
appendfsync everysec. - Assistant → an asynchronous replica, which may never hear the clerk’s last words.
- Three counters split by PNR → Redis Cluster’s hash slots.
The data model
Redis has one flat keyspace. Each key is a binary-safe string (keep it short, like user:9001:cart) holding one value of one type, optionally with a time to live (TTL). There are no tables, joins or secondary indexes in the core: you pick the structure so that your question is a single command.
| Type | What it holds | Typical interview use | Commands to name |
|---|---|---|---|
| String | Bytes or an integer, up to 512 MB | Cached pages, counters, idempotency keys, locks | GET, SET … NX EX, INCR (O(1)) |
| Hash | Field → value map under one key | Session, profile, token-bucket state | HSET, HGET (O(1)), HGETALL (O(N)) |
| List | Strings in insertion order | Recent items, a simple work queue | LPUSH, RPOP, BLMOVE, LTRIM |
| Set | Unique, unordered members | Who liked a post, deduplication | SADD, SISMEMBER (O(1)), SINTER |
| Sorted set | Unique members ordered by score (skip list plus hash table) | Leaderboards, delayed jobs, sliding-window logs | ZADD, ZINCRBY (O(log N)), ZREVRANGE, ZREVRANK |
| Stream | Append-only log with time-based IDs and consumer groups | Lightweight queue or event log | XADD, XREADGROUP, XACK |
| Geo index | A sorted set whose scores encode position | Nearby drivers or restaurants | GEOADD, GEOSEARCH |
| Bitmap | Bit operations on a string, up to 2³² bits | One “active today” bit per user ID | SETBIT, BITCOUNT |
| HyperLogLog | Distinct count in at most 12 KB, 0.81% standard error | Unique visitors | PFADD, PFCOUNT |
| Pub/Sub channel | Nothing stored: fire-and-forget fan-out | Typing indicators, invalidation pings | PUBLISH, SUBSCRIBE |
Redis 8.0 (May 2025) also folded JSON, time series, probabilistic filters, vector sets and a query engine into the core, but the classic types carry almost every interview design. Here they are for a fantasy-cricket app during an IPL match:
# Leaderboard for match 4512: one sorted set, score = fantasy points
ZINCRBY lb:match:4512 48 "user:9001" # a wicket earns user 9001 48 points
ZREVRANGE lb:match:4512 0 9 WITHSCORES # top 10, highest first
ZREVRANK lb:match:4512 "user:9001" # my rank (0-based), O(log N)
# Session: one hash that disappears after 30 idle minutes
HSET sess:7f3c uid 9001 lang hi cart_items 3
EXPIRE sess:7f3c 1800
Each line is one atomic command, so your application needs no locks around it.
One thread, atomic commands
Redis serves thousands of connections from one event loop, and only the main thread touches data: it runs each command to completion, then takes the next. Three consequences follow.
- Each command is atomic. Two clients running
INCR stock:sku42at once can’t both read 7 and write 8. - A slow command stalls everyone.
KEYS *,SMEMBERSon a million-member set orDELof a huge key blocks every other client; useSCAN, bounded ranges andUNLINK. - Commands use about one core per instance, so you add throughput with shards, not cores.
I/O threads don’t change this. With io-threads above 1 (off by default), extra threads read sockets, parse requests and write replies; the Redis 8.4 release notes report over 30% more throughput for a 90% GET workload on 4 cores. Commands still run on the main thread, one at a time.
Pipelines, transactions and scripts
Three ways to combine commands promise different things:
| Pipeline | MULTI … EXEC |
Lua script or Function | |
|---|---|---|---|
| Round trips | One per batch | One if pipelined | One |
| Atomic (nothing interleaves) | No | Yes | Yes |
| Can branch on a value it read | No | No (WATCH aborts on change) |
Yes |
| Rolls back on error | n/a | No | No |
| In Cluster | Any keys | All keys in one slot | All keys in one slot |
- Pipelining saves round trips: over a 250 ms link you’d get four requests a second however fast the server is, as the pipelining docs point out. Other clients’ commands can interleave.
MULTI/EXECruns the queued commands back to back but never rolls back.WATCHmakesEXECabort if a key you read has changed: optimistic check-and-set.- Lua scripts (
EVAL,EVALSHA) and Functions (Redis 7.0+) read, decide and write in one atomic step, which is what a token bucket needs. A script blocks the server; afterbusy-reply-threshold(5 s by default) other clients getBUSYerrors, but the script keeps running.EVALscripts sit in a cache that a failover empties, henceNOSCRIPTerrors; Functions are replicated with the data.
Redis 8.4 added SET key new IFEQ old (compare-and-set) and DELEX key IFEQ value (compare-and-delete), replacing some scripts.
Guarantees: what you can lose
Durability on one machine
Redis acknowledges a write once it is in memory. Whether it survives a crash depends on persistence:
- None. Fine for a cache the database can refill.
- RDB snapshots. Redis forks, and the child writes the dataset to one compact file while the parent keeps serving (copy-on-write). A crash loses everything since the last snapshot, usually minutes.
- Append-only file (AOF), off by default. Every write is logged and replayed on restart;
appendfsyncsets when the log reaches disk:always(fsync before replying; nothing acknowledged is lost, but every write waits for the disk),everysec(the default policy; about a second at risk) orno(the kernel decides; Linux usually flushes every 30 s). - Both, which the persistence docs suggest for PostgreSQL-like safety: AOF for the small window, RDB for backups and fast restarts.
A local fsync survives a power cut, not the loss of the machine; that needs replicas and off-box backups.
Replication is asynchronous
A primary streams writes to its replicas and replies to the client without waiting. Replicas report their offset about once a second and resume from it after a short disconnect. Three knobs trade latency for safety:
WAIT n timeoutblocks untilnreplicas acknowledge your earlier writes, or the timeout passes, and returns how many did.WAITAOF(Redis 7.2+) waits until those writes are fsynced to the AOF, locally or on replicas.min-replicas-to-writewithmin-replicas-max-lagmakes a primary refuse writes when too few replicas are close behind, capping how long a cut-off primary accepts doomed writes.
None of them makes Redis strongly consistent: the replication docs say WAIT does not make Redis CP, because failover promotes the best replica only on a best-effort basis.
“OK” from Redis means “in the primary’s memory”
An acknowledged write can vanish in a crash between fsyncs or in a failover before the replica caught up, and WAIT only makes the second less likely. Fine for a session or a cached page; not fine for a UPI debit or the last berth in a tatkal rush. Keep those in a database and let Redis hold the fast, rebuildable copy.
The guarantees at a glance
| Property | Default | Setting that changes it | What it costs |
|---|---|---|---|
| Atomicity | Per command, MULTI block (no rollback) or script |
Lua for read-decide-write | A slow script blocks the shard |
| Isolation | Each shard runs commands serially | Hash tags keep related keys on one shard | They share that shard’s capacity |
| Read freshness | Primary reads current; replica reads may be stale | Read from primaries only | All load on primaries |
| Durability on one node | RDB only; AOF off | appendonly yes with everysec or always |
Disk I/O; always ties writes to disk speed |
| Durability across failover | Acknowledged writes can be lost | WAIT, WAITAOF, min-replicas-to-write |
Latency; refused writes when replicas lag |
| Delivery | Pub/Sub is at-most-once | Streams with consumer groups: at-least-once | You must XACK and handle redelivery |
Ordering is simple: commands from one connection run in the order sent, and stream entry IDs only increase.
How it scales
Scale in this order, and say why you take each step.
- One primary. The limits are RAM and about one core of commands; the docs’ sample redis-benchmark run does about 180,000
SETs a second without pipelining. - Replicas for failover and stale-tolerant reads.
- Sentinel for automatic failover of that primary: at least three Sentinels on independent machines, a quorum to agree the primary is down (after 30 s in the sample config) and a majority to authorise the failover. Clients ask Sentinel where the primary is. It doesn’t shard.
- Redis Cluster when one primary can’t hold the data or absorb the writes.
Redis Cluster in five facts
- 16,384 hash slots. A key’s slot is
CRC16(key) mod 16384, and each primary owns ranges of slots. The cluster specification suggests about 1,000 nodes at most. - Hash tags. In
cart:{user42}onlyuser42is hashed, soorders:{user42}lands in the same slot. Multi-key commands,MULTIand scripts need every key in one slot, or you get aCROSSSLOTerror. Only database 0 exists. - Redirects, not proxies. Clients cache the slot map. A node that doesn’t own a slot replies
-MOVEDwith the right address: retry there and refresh the map. During a slot migration,-ASKredirects just one command, sent withASKING, and the map stays as it is. - Failover by majority. If a majority of primaries can’t reach a primary for
cluster-node-timeout(15 s by default), one of its replicas is elected, usually within a second or two. A primary on the minority side stops taking writes after the same timeout, and once it has been replaced, what it took meanwhile is lost. - Resharding moves slots. Key-by-key
MIGRATEstruggles with big keys; Redis 8.4 and Valkey 9.0 added atomic slot migration. Sharded Pub/Sub (SPUBLISH, Redis 7.0+) sends a channel to one node instead of broadcasting to all.
| Sentinel | Cluster | |
|---|---|---|
| Shards | One primary plus replicas | Many primaries sharing 16,384 slots |
| Who decides a failover | A quorum of Sentinels detects, a majority authorises | A majority of primaries |
| Default detection time | 30 s (sample config) | 15 s |
| Multi-key operations | Any keys | Same-slot keys only (hash tags) |
| Pick it when | Data and writes fit on one machine | You need more memory or write throughput than one primary |
Client-side sharding over independent instances with consistent hashing also works for pure caches, but resharding and failover become your problem; see distributed caching.
Limits and numbers
Treat the throughput row as a starting point for your own redis-benchmark run.
| Item | Number | Notes |
|---|---|---|
| Key or string value | 512 MB max | Big values hurt latency long before |
| Elements in a list, set or hash | 2³² − 1 (about 4.29 billion) | Memory runs out first |
| Hash slots | 16,384; about 1,000 nodes suggested max | Cluster spec |
| Default persistence | RDB saves at 3,600 s/1, 300 s/100, 60 s/10,000 changes; AOF off | redis.conf, Redis 8.10 |
maxmemory and policy |
0 (unlimited on 64-bit) and noeviction |
Set both for a cache |
maxclients |
10,000 | Default |
| Script busy threshold | 5 s | Then other clients get BUSY |
| Failure detection | Cluster 15 s; Sentinel 30 s | Plus 1–2 s for a cluster election |
| Throughput, docs’ sample run | About 180k SET/s at p50 0.143 ms; 1.5M SET/s and 1.8M GET/s with 16-command pipelines |
Hardware-specific |
| Fork cost | Page table ≈ RAM ÷ 4 KB × 8 bytes: 24 GB → 48 MB | 9–13 ms per GB on the good hosts the latency docs measured |
A sizing example. A UPI-style payments app keeps sessions for 8 million concurrent users at the evening peak, and MEMORY USAGE on sample keys shows about 500 bytes per session hash.
- Memory: 8M × 500 B = 4 GB. A snapshot or AOF rewrite forks, and every page written meanwhile is copied, so plan to fill only 60% of RAM: 4 GB ÷ 0.6 ≈ 6.7 GB, an 8 GB node.
- Traffic: if each app checks its session every 20 s, that is 8M ÷ 20 = 400k reads/s. The sample run did about 180k
SETs a second flat out; plan on half, about 90k per primary. 400k ÷ 90k ≈ 4.4, so 5 primaries, each with a replica.
Throughput, not memory, sets the shard count, which is typical. Per-key memory varies with encoding and version, so measure a realistic sample first.
When to pick it, and when not
| Redis | Memcached | PostgreSQL | Kafka | etcd or ZooKeeper | |
|---|---|---|---|---|---|
| Data model | Typed structures in RAM | Byte strings in RAM, 1 MB items by default | Relational tables on disk | Partitioned append-only log | Small keys or a tree of nodes |
| Durability | Optional: RDB, AOF | None | Commits fsynced to the WAL | Replicated log, retained for days | Every write committed by a quorum |
| Consistency | Async replicas; acknowledged writes can be lost | No replication | ACID; synchronous replicas optional | Ordered within a partition | Linearizable writes |
| Scale-out | Cluster with 16,384 slots | Client-side sharding; multithreaded | Read replicas, then sharding | More partitions and brokers | Doesn’t shard; 3 or 5 voters |
| Best for | Caches, counters, rankings, sessions, rate limits | A plain cache | The system of record | Event streams, replay, many consumers | Leader election, config, correctness locks |
Pick Redis when the data fits in RAM and is hot, short-lived or rebuildable, and you need atomic counters, rankings or sub-millisecond reads more than a zero-loss guarantee.
Don’t pick it when:
- It would be the only copy of money, orders or bookings: keep a database underneath.
- The dataset is large and mostly cold: RAM costs far more per GB than SSD, so use a disk-based store such as Cassandra or DynamoDB.
- You need a durable log with replay and many consumer groups: use Kafka. Streams suit a modest job queue.
- A lock or leader election protects correctness: use ZooKeeper or etcd with fencing tokens.
- You need ad-hoc queries, joins or reporting: use PostgreSQL or a warehouse.
Common interview usage
- Rate limiter. A token bucket per client key, such as
rl:{k_8f2a}:burst, updated by one Lua script and shared by every gateway; the limiter fails open if Redis is slow. - Live leaderboard and top-K trending. A sorted set per match or time window:
ZINCRBYper event,ZREVRANGE 0 9for the top 10,ZREVRANKfor “your rank”. Scores of record live in a database. - Sessions. A hash per session with
EXPIREas the idle timeout; logout is aDEL(see authentication and sessions). - A cache in front of a database, the most common role. The patterns live in the caching module: caching strategies, eviction policies and hot keys and stampedes.
- Seat holds and flash sales. In a BookMyShow-style booking,
SET hold:show77:B4-23 u9001 NX EX 600holds a seat for ten minutes, then expires; the final booking is a conditional write in the database (contention and double booking). In a flash sale, aDECRon a stock counter turns most buyers away before the order service. - Location. For ride hailing, food delivery or nearby friends, drivers
GEOADDtheir position every few seconds into a per-city key andGEOSEARCH … BYRADIUS 3 kmfinds candidates. Shard by city or grid cell so one key doesn’t take every update. - Queues and schedules. A stream with a consumer group gives at-least-once processing (
XREADGROUP,XACK,XAUTOCLAIMfor a dead consumer’s work); a sorted set scored by run-at time makes a delayed-job queue for a job scheduler. - Presence and fan-out. Pub/Sub pushes “Asha is typing” to the servers holding the right connections in WhatsApp or live comments; it is at-most-once, so only for signals you can drop.
- Counting.
INCRfor view counts flushed to the database, and HyperLogLog for unique visitors in web analytics.
In the interview
Name the structure and the command, not just “Redis”: “a sorted set per match; each event is a ZINCRBY, the top 10 is ZREVRANGE 0 9, my rank is ZREVRANK.” That shows why Redis fits and invites the right follow-up: what about 100 million players in one key?
Locks and the Redlock debate
A Redis lock is a key with an owner and an expiry:
SET lock:payout:881 9f2c41e7 NX PX 30000 # acquire: only if absent, expires in 30 s
DELEX lock:payout:881 IFEQ 9f2c41e7 # release (Redis 8.4+): delete only if still mine
The random value matters: if you stall past 30 seconds, someone else gets the lock, and a plain DEL would delete theirs (before 8.4, a short Lua script did the compare-and-delete).
Failover breaks it. The Redis lock docs spell it out: client A locks on the primary, the primary dies before replicating, the promoted replica has no key, and client B takes the same lock.
Redlock is the Redis creator’s answer: five independent primaries with no replication. A client sets the same key on all five and holds the lock only if it wins at least three in less time than the TTL.
Martin Kleppmann’s 2016 essay “How to do distributed locking” argued that this is the wrong tool when the lock guards correctness:
- Any lock with an expiry can have two holders: a process can pause (garbage collection, a page fault, a delayed packet) between checking its lock and writing, while the lock expires and passes on.
- The fix is a fencing token: a number that grows with every grant, sent with each write, and checked by the storage, which rejects anything older than the highest token it has seen. Redlock produces no such number, and a counter on one Redis node won’t do, because a failover can lose increments.
- Redlock’s safety also rests on timing: bounded pauses, bounded network delay and clocks that don’t jump.
Salvatore Sanfilippo (antirez) replied that Redlock re-checks the elapsed time after acquiring, so delays during acquisition can’t fool it; that a unique random token can drive a check-and-set on the resource; and that a store able to reject old tokens is already linearizable. He agreed Redis should use a monotonic clock.
Interviewers want you to classify the lock first:
- Efficiency locks (don’t send the reminder SMS twice, don’t run the hourly report on two workers): one Redis instance with
SET NX PXis fine; a rare double run is cheap. - Correctness locks (money, inventory): have the resource check a fencing token from a consensus system, such as a ZooKeeper
zxidor an etcd revision, or skip the lock and make the write itself conditional.
-- Storage-side fencing: a write carrying an older token is rejected
UPDATE seats SET holder = 'u9001', fence = 34
WHERE seat_id = 'B4-23' AND fence < 34;
More in distributed locking and design a distributed lock.
Going deeper: failure modes
Hot keys
A key lives in one slot on one primary, so a very popular key is capped by one core however many shards you add: think stock:sku42 in a sale or a celebrity’s profile. Cache it in the application for a second or two (Redis 6 client-side caching can push invalidations), read from replicas if staleness is fine, or split a counter into stock:{sku42:0} … stock:{sku42:7}. Redis 8.6 added a HOTKEYS command to find them.
Big keys and slow commands
A 50-million-member sorted set or a 200 MB string blocks the server on DEL (use UNLINK), floods the network when read whole, and causes spikes when replicated or migrated. Find them with redis-cli --bigkeys and cap growth with LTRIM, XTRIM or ZREMRANGEBYRANK. KEYS, unbounded ranges, big set intersections and loops in Lua block the event loop the same way: watch SLOWLOG and iterate with SCAN.
Memory full
With the default noeviction, a full instance rejects writes that need memory; with maxmemory 0, the operating system may kill the process instead. For a cache, set maxmemory and a policy: the eviction docs call allkeys-lru a good default. volatile-* policies act like noeviction when no key has a TTL, and replication buffers don’t count against maxmemory, so leave headroom. Redis 8.6 added allkeys-lrm, which evicts the least recently modified keys. Theory in cache eviction policies.
Fork stalls
Snapshots and rewrites fork, and the main thread copies the page table: 48 MB for a 24 GB instance. At the 9–13 ms per GB the latency docs measured on good hosts, that is a pause of roughly 0.2–0.3 s; old Xen VMs took 239 ms per GB, nearly 6 s at 24 GB. Disable transparent huge pages, and prefer more, smaller shards.
Persistence off, auto-restart on
A primary without persistence that a supervisor restarts comes back empty, and its replicas sync the empty dataset, wiping their own copies. The replication docs warn about exactly this: turn persistence on or disable automatic restarts.
Redis, Valkey and the licence
| When | What happened |
|---|---|
| 20 Mar 2024 | After fifteen years under BSD, Redis Inc. announced that releases from 7.4 on would be dual-licensed under RSALv2 and SSPLv1, neither OSI-approved; cloud providers would need an agreement to offer them as a service |
| 28 Mar 2024 | The Linux Foundation announced Valkey, a BSD-3 fork of Redis 7.2.4 backed by AWS, Google Cloud, Oracle, Ericsson and Snap |
| 1 May 2025 | Redis 8.0 added AGPLv3, an OSI-approved licence, as a third option |
| Oct 2025 on | Both lines keep shipping: Valkey 9.0 and Redis 8.4 each added atomic slot migration |
For a design interview nothing on this page changes; the licence matters only if you build a hosted service on top.
Cheat sheet
| Topic | Remember |
|---|---|
| Atomicity | Every command, MULTI/EXEC block (no rollback), Lua script or Function |
| Structures → uses | Sorted set: rankings · hash: sessions · string: counters, locks · stream: queues · geo: nearby · HyperLogLog: unique counts |
| Durability | RDB: minutes · AOF everysec: about 1 s · AOF always: nothing acknowledged, slowest |
| Replication | Asynchronous; WAIT and WAITAOF narrow the loss window, never close it |
| High availability | Sentinel: one primary, at least 3 Sentinels · Cluster: 16,384 slots, majority of primaries |
| Cluster rules | CRC16(key) mod 16384; hash tags for multi-key; MOVED updates the map, ASK is one command |
| Defaults | noeviction, maxmemory 0, node timeout 15 s, I/O threads off |
| Hard limits | 512 MB per key or string; 2³² − 1 elements per collection; HyperLogLog 12 KB |
| Locks | SET NX PX, release with DELEX IFEQ; for correctness, a fencing token checked by the resource |
| Not for | The only copy of money or orders, huge cold datasets, durable replayable logs |
How to say it in the interview
“I’d use Redis for the hot, rebuildable state: the cache in front of Postgres, the rate-limit counters and a sorted-set leaderboard per match. Redis executes commands on one thread, so each command and Lua script is atomic and I need no application locks around counters. I’d enable AOF with fsync every second, so a crash costs about a second of writes, and a failover can lose a little more because replication is asynchronous. That’s fine: Postgres is the source of truth. To scale I’d use Redis Cluster with the user ID as a hash tag, and I’d watch for hot keys during the sale.”
Is Redis single-threaded? Then how does it scale? Command execution is single-threaded, which is what makes commands atomic; I/O threads (off by default) only parallelise socket reads, parsing and replies. You scale by sharding across primaries with Redis Cluster.
Can Redis lose a write it acknowledged?
Yes. A crash loses writes since the last fsync: about a second with everysec, minutes with RDB only. A failover loses writes the replica hadn’t received. WAIT tells you how many replicas have a write, but it doesn’t make Redis CP.
How would you build a leaderboard for 100 million players? One sorted set can hold them with O(log N) updates, but it is one key on one shard: hot and big. Split by league or region, merge each shard’s top 100 for the global top 100, and estimate global rank from counts per score range. The leaderboard design goes deeper.
Why not Redlock for a payment lock? Any lease-based lock can have two holders after a pause or a delayed packet, and Redlock issues no fencing token for the storage to check. Take a monotonic token from a consensus store and have the database reject stale ones, or make the write conditional.
What’s the difference between MOVED and ASK?
MOVED means the slot now lives on another node: retry there and refresh your slot map. ASK appears mid-migration: send only this command to the other node, prefixed with ASKING, and keep your map.
Where to go next
- Caching strategies: the patterns Redis is most often used for.
- Hot keys, cache stampede and invalidation: failure modes of a Redis cache tier.
- Design a rate limiter: Lua scripts, hash tags and failing open in a full design.
- Design a live leaderboard: sorted sets at scale.
- Distributed locking: leases, fencing tokens and lock services.
- ZooKeeper and etcd: consensus when correctness beats speed.
- CAP theorem and PACELC: why acknowledging before replicating buys latency and costs lost writes.
References and further reading
- Redis data types (Redis documentation)redis.ioThe current list of native types, including those bundled since Redis 8, with per-type limits (512 MB strings, 2³² − 1 elements, 12 KB HyperLogLog) on the linked pages.
- Redis persistenceredis.ioRDB snapshots versus the append-only file, the three appendfsync policies and what each can lose, and fork-based rewrites.
- Redis replicationredis.ioAsynchronous replication, partial resync, why WAIT does not make Redis CP, min-replicas-to-write, and the persistence-off auto-restart trap.
- Redis Cluster specificationredis.io16,384 hash slots, CRC16, hash tags, MOVED and ASK redirections, failover timing and the windows in which acknowledged writes are lost.
- Redis programmability: scripts and functionsredis.ioAtomic, blocking execution of Lua scripts and Functions, read-only variants and the 5-second busy-reply-threshold.
- Diagnosing latency issues (Redis documentation)redis.ioThe single-threaded execution model, slow commands and KEYS versus SCAN, fork cost per GB, and transparent huge pages.
- Distributed locks with Redisredis.ioSET NX PX locking, safe release with DELEX (Redis 8.4) or a script, why failover breaks single-instance locks, and the Redlock algorithm.
- How to do distributed locking (Kleppmann, 2016)martin.kleppmann.comEfficiency versus correctness locks, fencing tokens, and why Redlock’s safety depends on timing assumptions.
- Is Redlock safe? (antirez, 2016)antirez.comThe Redis creator’s reply: re-checking elapsed time after acquiring, unique tokens for check-and-set, and the move to a monotonic clock.
- Redis is now available under the AGPLv3 open source license (Redis, 2025)redis.ioWhy Redis moved to RSALv2/SSPLv1 in 2024, and the AGPLv3 option added with Redis 8 alongside the Redis Stack features.