Python Read Replica Patterns — Core Concepts

Why read replicas exist

Most web applications are read-heavy. A typical ratio is 90% reads to 10% writes. A single database server can become a bottleneck not because of writes, but because thousands of read queries compete for CPU, memory, and I/O.

Read replicas solve this by duplicating the database. Writes go to one primary server, and reads are distributed across multiple replicas. Each replica is a full copy of the primary, updated asynchronously via replication.

How replication works

  1. The primary database processes a write (INSERT, UPDATE, DELETE).
  2. It records the change in a write-ahead log (WAL in PostgreSQL, binlog in MySQL).
  3. Replicas continuously pull changes from this log and apply them locally.
  4. After a brief delay (replication lag), the replica matches the primary.

Replication lag

The gap between a write on the primary and its appearance on the replica is called replication lag. Typically 10–100 milliseconds, but can spike to seconds during heavy write load or network issues.

Lag matters in specific scenarios:

  • Read-your-own-writes — a user submits a form, then immediately sees a page that reads from a replica. If the replica hasn’t caught up, the user sees old data.
  • Causal consistency — User A posts a comment, User B reads it, but User B’s request hits a lagging replica and sees nothing.

Routing strategies

Route all reads to replicas (simplest)

Every SELECT goes to a replica. Works for dashboards, reports, and pages where slight staleness is acceptable.

Read-after-write routing

After a write, route that user’s subsequent reads to the primary for a short window (5–10 seconds). This guarantees the user sees their own changes.

Query-type routing

Route specific queries based on freshness requirements:

  • Listing pages → replica (slightly stale is fine)
  • Order status after payment → primary (must be current)
  • Admin reports → dedicated reporting replica

When replicas help

  • Read-heavy workloadsAPIs serving product pages, user profiles, search results.
  • Reporting and analytics — heavy queries that would slow down the primary.
  • Geographic distribution — replicas in different regions reduce latency for distant users.
  • Failover — a replica can be promoted to primary if the original fails.

When replicas don’t help

  • Write-heavy workloads — replicas don’t reduce write load on the primary. Every write still goes to one server.
  • Small databases — if the primary isn’t under pressure, replicas add complexity without benefit.
  • Strong consistency requirements — if every read must return the latest data, replicas add lag that must be worked around.

The read replica landscape

DatabaseReplication typeMax replicasLag monitoring
PostgreSQLStreaming (async/sync)Unlimitedpg_stat_replication
MySQLBinlog (async/semi-sync)UnlimitedSHOW SLAVE STATUS
AWS RDSManaged async15 per regionCloudWatch
Cloud SQLManaged async10GCP metrics

Common misconception

Adding replicas doesn’t double your database capacity. Replicas only help with reads. If your bottleneck is write throughput, connection limits, or a poorly indexed query, replicas won’t solve it. Always profile your database workload before adding replicas — you might just need a better index.

The one thing to remember: read replicas scale your database’s read capacity by distributing queries across copies, but they introduce replication lag that your Python application must account for in routing decisions.

pythondatabasesscaling

See Also

  • Ci Cd Why big apps can ship updates every day without turning your phone into a glitchy mess — CI/CD is the behind-the-scenes quality gate and delivery truck.
  • Containerization Why does software that works on your computer break on everyone else's? Containers fix that — and they're why Netflix can deploy 100 updates a day without the site going down.
  • Python 310 New Features Python 3.10 gave programmers a shape-sorting machine, friendlier error messages, and cleaner ways to say 'this or that' in type hints.
  • Python 311 New Features Python 3.11 made everything faster, error messages smarter, and let you catch several mistakes at once instead of stopping at the first one.
  • Python 312 New Features Python 3.12 made type hints shorter, f-strings more powerful, and started preparing Python's engine for a world without the GIL.