Read replicas and follower reads: the cost ladder
Which ways of reading buy freshness, and with which currency?
Adding a replica multiplies write work by one unit and divides nothing on the write side. So read replicas pay only when reads dominate. The break-even is explicit in the per-node work (R·w + r)/N, a ratio you can compute instead of a default you adopt.
What makes the mechanism interesting is not capacity but the ladder of ways to read. Each rung buys freshness with a different currency:
| Mechanism | Extra RTT | Depends on | Pays in |
|---|---|---|---|
| Read from the leader, naively | 0 | nothing, and it is unsafe, since a partitioned old leader still believes it leads | correctness |
| ReadIndex (confirm leadership with one heartbeat round, then serve locally) | 1 to a quorum, no disk | quorum reachability | latency |
| Leader lease | 0 | a bound on clock drift | a timing assumption in the safety argument |
| Quorum read (leaderless) | 1 to R nodes | R + W > N | latency on every read |
| Nearest follower, stale | 0 | nothing | unbounded staleness |
| Follower read at a timestamp | 0 if caught up, else it waits | a closed/safe-timestamp signal | staleness converted into latency |
The last rung is the interesting one. A follower that knows it has applied everything up to time T can serve any read at or before T locally and correctly, and it must wait for anything later. That converts an unbounded, invisible cost (staleness that the reader cannot detect) into a bounded, visible one (a wait that the reader can measure). It is an exchange of cost currencies applied deliberately: staleness is traded for latency. The same move appears in cache verification, which can bill an RTT instead of a payload.
Note also the one rung where a timeout touches safety. Everywhere else here, tuning a timeout costs availability only. A leader lease makes correctness depend on a clock-drift bound. This is why systems that use leases pair them with fencing on the write path, and why ReadIndex exists: it trades a round trip for the removal of the assumption.
The lag asymmetry
A leader applies writes using many cores. A follower historically replays them with one, because the log records an order and not a dependency graph. Under load, the apply path is narrower than the produce path, so lag does not stay constant: it grows, like a queue whose arrival rate is above its service rate. Little's Law (the number of items in a system equals arrival rate times time spent in the system) has no steady state there: the queue grows without limit. The usual fix is to enrich the log with enough dependency information to re-parallelise safely (MySQL's writeset-based parallel apply, Postgres's parallel-recovery work).
Ordering costs parallelism on the way in and costs it again on the way out, and the follower is where you pay the second time. People rarely look for it there.
Compression: read scaling is free only if you pay staleness, and every mechanism that removes staleness reintroduces a round trip, a clock assumption, or a wait.