What a replica actually is

Free preview 3 min to read

A read replica is a second database that copies everything the first one does, a little later. Both halves of that sentence matter, and the second half is where every replica problem comes from.

The mechanism

The primary writes every change to a log before applying it. In Postgres that's the write-ahead log, a durable, ordered record of every modification.

A replica connects to the primary, streams that log and replays it. It isn't running your queries again. It's applying the same byte-level changes in the same order, which is why a replica can't drift into a different state. It can only be behind.

flowchart LR
  W["a write arrives"] --> P["primary applies it"]
  P --> L["and appends it to the write-ahead log"]
  L --> S["replica streams the log"]
  S --> R["replica replays it, a little later"]
  R --> B["same state, some milliseconds behind"]

A replica is read-only, and that's enforced. A write attempted on one raises an error rather than quietly diverging.

Asynchronous by default

The primary doesn't wait for the replica. It applies a write, appends to the log and answers the client. Whether the replica has caught up isn't part of that transaction.

That's a deliberate trade, and it's the right default. The alternative, synchronous replication, where the primary waits for an acknowledgement, makes every write as slow as the slowest replica and turns a replica outage into a primary outage.

What you get for that speed is a window in which the two disagree. That window is called replication lag, and it's usually milliseconds. "Usually" carries a lot of weight in that sentence, and lesson 3 is about what happens when it isn't.

What a replica is not

It isn't a backup. A backup is a point-in-time copy you can go back to. A replica applies everything, including the DELETE you regret, within milliseconds, on both machines.

It isn't a shard. Sharding splits data so each server holds a different part. A replica holds all of it, so it does nothing for a database too large for one machine. It helps only when the problem is too many reads, not too much data.

It isn't automatic failover. A replica can be promoted to primary, but something has to decide to promote it, point the application at it, and make sure the old primary never comes back thinking it's still in charge. That machinery is separate, and it's the hard part.

What it is for

It does one thing: it moves read traffic off the primary.

That's worth stating narrowly, because people often reach for a replica as a general "make the database faster" move. It doesn't make any single query faster, since the replica runs the same query on the same data with the same plan. It makes the primary less busy, which makes the queries still running there faster.

Key takeaways

  • A replica streams the primary's write-ahead log and replays it. It can be behind, but never different.
  • Replication is asynchronous by default: the primary answers the client without waiting for the replica.
  • The gap between them is replication lag, usually milliseconds.
  • A replica isn't a backup, a shard or failover. It applies your mistakes too, holds all the data, and doesn't promote itself.
  • It doesn't make a query faster. It makes the primary less busy.
Lesson 1 of 7 · free

Keep going with lesson 2

The reading role

Rails declares writing and reading roles in connects_to, marks replicas with replica: true, and routes explicitly with connected_to.

A free account also gives you the quizzes, your progress and notes, and the discussion.

Type to start searching...