Decorative background gradient
Back to Blog
DatabasePostgreSQLSystem Design

Database Indexing and Read Replicas — A Practical Guide

How to choose the right database indexes, avoid the ones that quietly hurt write performance, and scale reads with replicas without introducing replication lag bugs.

Database Indexing and Read Replicas — A Practical Guide

Two techniques do most of the heavy lifting when a database starts to strain under load: indexing, which makes individual queries faster, and read replicas, which spread read traffic across more hardware. Both are simple in concept and easy to misuse — over-indexing quietly kills write throughput, and replicas introduce a consistency gap that shows up as confusing, hard-to-reproduce bugs if you don't design around it.

How Indexes Actually Work

An index is a separate, sorted data structure (typically a B-tree) that lets the database find rows matching a condition without scanning the whole table.

sql

Without this index, SELECT * FROM orders WHERE user_id = 123 has to scan every row in the table. With it, the database can jump directly to the matching rows — the difference between O(n) and roughly O(log n) lookup time. On a table with a few hundred rows this doesn't matter; on a table with tens of millions, it's the difference between a 5ms query and a 5-second one.

The Cost Side: Why You Can't Index Everything

Every index has to be maintained on every write to that table.

sql

This is the part teams miss: an index that speeds up one report query might be silently adding latency to every single write in the system, forever, whether or not that report ever runs. Before adding an index, check whether the query it would help actually runs often enough, and on a large enough table, to be worth that ongoing write cost. A good rule of thumb — index for your top 5-10 slowest or most frequent queries, not for every column that theoretically could be filtered on.

Composite Indexes and the Leftmost Prefix Rule

A composite (multi-column) index only helps queries that filter using its columns in order, starting from the left.

sql

If you regularly query by status alone as well, you need a separate index on status — the composite index above won't serve that query efficiently. Order the columns in a composite index by how they're actually queried, not alphabetically or by table definition order.

Verifying an Index Is Actually Used

Adding an index doesn't guarantee the query planner will use it — always verify with EXPLAIN ANALYZE.

sql
text

If you instead see Seq Scan on a large table where you expected an index to be used, the planner has decided a full scan is cheaper — often because the table is small enough that the difference doesn't matter, or the column has low cardinality (few distinct values), where an index provides little benefit over a scan. Don't assume an index is helping; confirm it.

Scaling Reads with Read Replicas

Once indexing has been exhausted, the next lever is spreading read traffic across replicas — copies of the primary database that stay in sync via replication and serve read-only queries.

text
ts

This lets you scale read throughput horizontally by adding more replicas, independent of the primary — useful because most applications are read-heavy by a wide margin.

The Replication Lag Problem

Replication is asynchronous by default in most setups, which means there's a real, if usually small, delay between a write landing on the primary and that write appearing on a replica.

ts

This is the single most common bug introduced by adding read replicas: a user submits something, gets redirected to a page that reads it back, and sees it missing or outdated because the read landed on a replica that's a few milliseconds (or, under load, seconds) behind. The fix is to route read-your-own-write scenarios back to the primary explicitly.

ts

A practical rule: default reads to replicas for anything that tolerates slight staleness (dashboards, public listings, search), and explicitly route to the primary for anything that must reflect a write the current request or user just made.

Key Takeaways

Index the queries that are actually slow and frequent, not every column — each index adds real write overhead that persists whether or not the query it supports ever runs. Composite indexes only help queries that filter using their columns from the leftmost one inward, and EXPLAIN ANALYZE is how you confirm an index is actually being used rather than assumed to help. Read replicas scale read throughput well, but asynchronous replication means read-your-own-write reads need to be routed to the primary explicitly, or users will intermittently see their own just-submitted data as missing or stale.

Frequently Asked Questions

How do I know which columns to index?

Index columns that appear in WHERE clauses, JOIN conditions, and ORDER BY clauses of your slowest or most frequent queries — not every column. Use EXPLAIN ANALYZE on your actual production queries to find sequential scans on large tables, since those are the strongest signal that an index is missing.

Why does adding too many indexes hurt performance?

Every index has to be updated on every INSERT, UPDATE, or DELETE to the table it belongs to, so each additional index adds write overhead and disk space. A table with ten rarely-used indexes can have noticeably slower writes than the same table with three well-chosen ones, even though reads might look identical.

What is replication lag and why does it matter?

Replication lag is the delay between a write landing on the primary database and that same data appearing on a read replica, since most replication is asynchronous. It matters because a user who just wrote data and then reads it back can hit a replica that hasn't received the write yet, seeing outdated or missing data despite having just saved it.

Should all reads go to replicas?

No — reads that need to reflect a write the same user just made (read- your-own-writes) should go to the primary, since replicas may lag behind by milliseconds to seconds. Reads that tolerate slight staleness — dashboards, public listings, analytics — are ideal candidates for replicas.

Working on something similar? Take a look at my services and case studies, or book a free call to talk about your idea.

Related Articles

Trending Topics