← Back to Database and Storage

Read Replica Pattern

Read replica architecture for scaling queries away from the primary database.

Database and StorageDatabase ReplicationRead Scalability

The read replica pattern is one of the simplest ways to scale a database-backed application. The idea is to keep one primary database responsible for writes and replicate its data to one or more replicas that serve read traffic. This allows the system to absorb many more queries without forcing every request through the same machine.

It is attractive because the application model stays familiar. The primary still owns inserts, updates, and deletes. Replicas mostly answer selects. Many teams can adopt the pattern without rewriting their domain model or abandoning SQL.

Why teams introduce replicas

Most production systems are read-heavy. Users browse products, open dashboards, inspect history, and refresh lists far more often than they change data. Offloading those reads to replicas reduces primary CPU, memory pressure, and disk contention. It also gives some operational flexibility because reporting or analytics reads can be isolated from transactional traffic.

How it works

After the primary commits a write, replication transports that change to each replica. Depending on the database, this may happen through a write-ahead log, binary log, or another change stream. The replica replays the change locally and gradually converges on the same state.

This architecture is usually asynchronous because synchronous replication would force the primary to wait for replicas on every commit, which increases latency and reduces availability during network problems.

Replication lag is the central tradeoff

Asynchronous replication creates the main weakness of the pattern: replication lag. A user can submit an order successfully, then immediately read from a replica that has not replayed the new row yet. From the user’s point of view, the system looks broken even though the write succeeded.

This is the classic read-after-write consistency problem. Lag might be milliseconds under normal load and seconds or longer during failover, maintenance, or bursts.

Common mitigations

One mitigation is to route all latency-sensitive or correctness-sensitive reads to the primary. Another is session stickiness: after a user writes, that user reads from the primary for a short period. Some systems track the last write position and only read from a replica once it has caught up past that point.

These strategies reduce inconsistency but also reduce the amount of traffic you can safely offload. That is the real tradeoff. Replicas improve scale, but every guarantee stronger than eventual consistency pushes some read traffic back toward the primary.

Other operational concerns

Replica routing needs to account for health and freshness. A replica that is alive but badly behind may be worse than a replica that is down because it serves stale truth. Query pools should therefore consider both availability and lag.

Failover adds more complexity. If the primary fails, promoting a replica is possible, but clients, connection strings, and write routing all need to converge quickly. Any writes acknowledged only on the old primary but not yet replicated may be lost.

When the pattern fits

The pattern works best for applications with heavy read traffic, modest tolerance for slightly stale data, and a relational model that still benefits from a primary source of truth. It is less appropriate when every read must reflect the latest write immediately or when global write distribution is the harder problem.

Read replicas are powerful because they are simple. They let you buy read scale with familiar database machinery. The price is living with lag and designing explicitly around it.