Read Replicas
A read replica is a Redis server that maintains a continuously updated copy of another Redis server’s (the master, sometimes called primary) dataset, and serves read traffic from that copy. Replicas let you scale reads horizontally across many servers, survive a master’s disk or process failure without losing the dataset, and offload expensive operations (backups, analytics scans) away from the server that’s handling writes. Understanding how replication actually propagates data — and what it does not guarantee — is essential before you rely on it in production.
Overview / How it works
Redis replication is asynchronous and follows a leader-follower model: one master accepts all writes, and one or more replicas connect to it and receive a continuous stream of the write commands the master executes. A replica never generates its own independent writes to replicated keys — by default, a replica is read-only and simply mirrors whatever the master does, in the same order the master did it.
When a replica first connects to a master (or reconnects after being offline for too long), it performs a full synchronization: the master forks a child process that writes an RDB snapshot of the entire dataset, streams that snapshot to the replica, and simultaneously buffers any new write commands that arrive during the transfer in a replication backlog. Once the replica loads the RDB snapshot into memory, the master sends it the buffered commands so the replica catches up to the exact point in time the snapshot was taken. From then on, the master simply forwards every write command it processes to all connected replicas over a persistent TCP link, and replicas apply them one at a time, in the same order — the same single-threaded execution guarantee that makes commands atomic on the master also means the replica’s dataset evolves through the exact same sequence of state transitions.
If a replica briefly disconnects (a network blip) and reconnects before the backlog buffer wraps around, Redis performs a partial resynchronization instead of a full one: the replica tells the master its last known replication offset and replication ID, and the master just replays the missing slice of the backlog. This is why INFO replication exposes a master_replid and a numeric master_repl_offset — together they identify exactly how far a replica has progressed through the write stream, and whether a reconnect can be resumed cheaply or requires a full RDB transfer again.
Because propagation is asynchronous, a write is considered successful on the master as soon as the master itself has applied it — the client does not wait for any replica to acknowledge it. This means there is always a small window, replication lag, during which a replica’s view of the data is slightly behind the master’s. Under normal network conditions this lag is usually sub-millisecond to a few milliseconds, but it can grow under load, on a slow network link, or if a replica is busy with a large operation. Plain Redis replication also does not perform automatic failover on its own: if the master dies, replicas keep serving stale reads forever unless something (an operator, or Redis Sentinel, covered in a later lesson) promotes one of them to master.
Syntax
REPLICAOF host port
REPLICAOF NO ONE
host port— the address of the server to replicate from. Issuing this on a server makes it a replica of that master; it triggers a sync (full or partial) and begins applying the master’s write stream.NO ONE— detaches the server from whatever master it was replicating from and turns it into an independent, writable master. This is the command you run to manually promote a replica.
SLAVEOF is the original name for this command and is kept as an alias for backward compatibility; REPLICAOF is the current preferred name.
| Command | Purpose | Time Complexity |
|---|---|---|
REPLICAOF host port |
Start replicating from a master | O(1) to issue (sync itself is O(N) in dataset size) |
REPLICAOF NO ONE |
Stop replicating; become a standalone master | O(1) |
ROLE |
Report whether this instance is a master or replica, plus offsets | O(1) |
INFO replication |
Detailed replication status and statistics | O(1) |
WAIT numreplicas timeout |
Block until N replicas have acknowledged all prior writes, or timeout | O(1) |
Examples
Example 1: Inspecting replication state on a standalone server
Every Redis server starts out as a master with zero replicas attached. ROLE and INFO replication are the two commands you’ll use constantly to check replication status, and they work identically whether you’re on a master or a replica.
ROLE
Output:
1) "master"
2) (integer) 0
3) (empty array)
The reply tells you this server is a master, its current replication offset is 0 (no writes have happened yet), and it has an empty list of connected replicas (each connected replica would appear here as an array of [ip, port, offset]). Running INFO replication on the same fresh server would show a role:master line, connected_slaves:0, a randomly generated 40-character hex master_replid, and master_repl_offset:0.
Example 2: Using WAIT to confirm replication of a write
Because replication is asynchronous, a write returning OK only means the master accepted it — not that any replica has it yet. WAIT lets you block until a given number of replicas have acknowledged the writes issued so far on that connection, which is useful when a specific write is important enough that you want some durability guarantee beyond the master alone.
SET orders:1042:status "paid"
WAIT 0 100
Output:
OK
(integer) 0
The SET succeeds immediately. WAIT 0 100 asks Redis to wait until 0 replicas have acknowledged the write, with a 100ms timeout — since the required count is already 0, it returns immediately with the number of replicas that had actually acknowledged (also 0, since none are attached here). On a server with real replicas, you’d pass a positive numreplicas and the command would block (up to the timeout) until that many replicas confirmed receipt of the replication stream up to this point.
Example 3: Setting up an actual replica (illustrative, two servers)
This is what you’d run in a real deployment with a master at 203.0.113.10:6379 and a second Redis process meant to become its replica. You cannot demonstrate this against a single instance, so treat this as a reference, not something to paste into one running server.
REPLICAOF 203.0.113.10 6379
INFO replication
Output:
OK
# Replication
role:slave
master_host:203.0.113.10
master_port:6379
master_link_status:up
master_last_io_seconds_ago:0
master_sync_in_progress:0
slave_read_only:1
connected_slaves:0
master_replid:8c1e0f2a...
master_repl_offset:15042
slave_repl_offset:15042
REPLICAOF returns OK immediately and performs the actual connection and sync in the background; polling INFO replication afterward is how you confirm master_link_status:up (fully synced and streaming) rather than down (still connecting or the link dropped). slave_repl_offset catching up to master_repl_offset tells you the replica has applied every write the master has sent so far.
How it works step by step
- An operator (or Sentinel) runs
REPLICAOF master_host master_porton the replica. - The replica opens a connection to the master and performs a handshake (
PING, exchanging listening port and capabilities, thenPSYNCwith its last known replication ID and offset). - If the master recognizes the replication ID and still has the requested offset in its backlog, it performs a partial resync — only the missing commands are sent. Otherwise it performs a full resync: it forks, the child writes an RDB snapshot, and the snapshot streams to the replica while new writes queue in the backlog.
- The replica discards its old dataset, loads the RDB snapshot, then applies the buffered commands sent afterward to catch up to the master’s exact current state.
- From that point, every write command the master executes (as part of its own single-threaded command processing) is propagated over the same link, applied by the replica in identical order.
- The replica continuously reports its offset back to the master (replication ACKs), which is what lets
WAITandINFO replicationreport how caught-up each replica is.
Common Mistakes
Mistake 1: Trying to write directly to a replica. Replicas are read-only by default specifically so that they stay a faithful mirror of the master. Writing to one directly fails:
SET session:abc123 "active"
Output:
(error) READONLY You can't write against a read only replica.
Route all writes to the master. If you need a replica to accept writes temporarily (e.g., during testing), that’s a signal you actually want REPLICAOF NO ONE to promote it, not to bypass read-only mode.
Mistake 2: Reading your own write from a replica and expecting it immediately. Because replication is asynchronous, a client that writes to the master and then immediately reads the same key from a replica can get a stale (or missing) value — the write simply hasn’t arrived yet. If an application flow requires strict read-your-own-writes consistency, read that specific key back from the master, or use WAIT after the write to confirm propagation before routing the follow-up read to a replica.
Mistake 3: Treating a replica as your only backup. A replica faithfully replicates everything the master does — including an accidental DEL, an expired key, or a corrupted write. If someone deletes data on the master, the replica deletes it too, usually within milliseconds. Replicas protect you against a machine dying, not against application-level mistakes; you still need independent RDB/AOF backups.
Mistake 4: Assuming failover happens automatically. Plain master-replica replication has no built-in failure detection or promotion logic. If the master goes down, replicas just sit there, read-only, replicating from a dead link, until a human runs REPLICAOF NO ONE on one of them or an automated system like Sentinel does it. Don’t rely on raw replication alone for high availability.
Best Practices
- Monitor
master_repl_offseton the master versusslave_repl_offseton each replica (viaINFO replication) to track replication lag, and alert if the gap grows. - Use
WAITfor writes where losing the write on master failure would be unacceptable, but understand it adds latency — don’t use it on every write in a high-throughput path. - Keep replicas read-only (the default) unless you have a specific, deliberate reason to change it — it’s your safety net against accidental writes landing on the wrong server.
- Place replicas in a different availability zone or physical host than the master so a single hardware or network failure doesn’t take out both.
- Don’t substitute replication for backups — keep RDB snapshots and/or AOF persistence independent of your replica count.
- For automatic failure detection and promotion, use Redis Sentinel or Redis Cluster rather than hand-rolling failover logic.
- Size your replication backlog large enough (relative to your write volume and typical network blip duration) that brief disconnects can partial-resync instead of triggering an expensive full resync.
Practice Exercises
- On a single local Redis instance, run
ROLEandINFO replicationand identify every field that would change once a real replica connects (hint:connected_slaves,master_repl_offset, and the array inROLE‘s third element). - Write a few keys with
SET, then runWAIT 1 200. On a standalone server with no replicas, predict and verify what it returns and why that differs from what it would return with one replica attached and caught up. - Sketch out (in words, not code) the sequence of Redis commands and
INFO replicationchecks you’d use to manually fail over from a dead master to one of its replicas, including how you’d stop the old master from ever being written to again once it’s back online.
Summary
- A read replica is an asynchronous, continuously updated copy of a master’s dataset, used for read scaling and redundancy.
- Replication starts with a full sync (RDB snapshot + buffered backlog) and, after brief disconnects, can resume with a cheaper partial resync using the replication ID and offset.
- Replicas are read-only by default; direct writes fail with a
READONLYerror. - Because propagation is asynchronous, replicas can lag behind the master — use
WAITwhen you need confirmation that N replicas have received a write. REPLICAOF host portattaches to a master;REPLICAOF NO ONEdetaches and promotes to a standalone master — but nothing does this automatically without Sentinel or Cluster.- Replication is not a substitute for backups: it faithfully replicates deletions and corruption along with legitimate writes.
