Scalability & Performance

Database Scaling Patterns: Replicas, Shards, Pools, and Query Tuning

Master database scaling with read replicas, sharding, materialized views, denormalization, connection pooling, and query optimization techniques.

read replicasshardingmaterialized viewsconnection poolingquery optimization

Why Database Scaling Is Hard

Application servers are often easy to scale horizontally because they can be stateless. Databases are harder because they own durable state, consistency, indexes, transactions, locks, and replication.

Key idea: Scale databases by first reducing unnecessary work, then splitting reads, then splitting writes. Sharding is powerful, but it should not be your first move.


Scaling Decision Path

Start with evidence. A database can be slow because of missing indexes, too many connections, lock contention, poor query plans, hot rows, network latency, or storage saturation.


Read Replicas

Read replicas copy data from a primary database and serve read traffic.

BenefitTrade-off
Scales read throughputReplication lag
Reduces primary loadRead-after-write inconsistency
Improves regional latencyMore operational complexity
Supports analytics readsReplica staleness

Read-After-Write Strategies

StrategyHow It Works
Read your writes from primaryRoute fresh reads to primary for a short window
Session consistency tokenRead from replica only after it catches up
Sticky read routingSame user reads primary briefly after writing
UI delay or optimistic updateShow local state until replica catches up
⚠️

Replica lag is a product behavior: If a user updates a profile and immediately sees old data, that is not just a database detail. Design the read path intentionally.


Sharding

Sharding splits data across multiple databases so each shard owns a subset of the data.

Sharding Strategies

StrategyHow It WorksRisk
Hash-basedhash(key) % shard_countRebalancing when shard count changes
Range-basedKey ranges per shardHot ranges and uneven growth
Directory-basedLookup service maps key to shardDirectory becomes critical dependency
Geo-basedData lives near usersCross-region queries get harder
Tenant-basedEach tenant maps to shardLarge tenants can become hot

Choosing a Shard Key

A good shard key:

  1. Appears in most queries.
  2. Spreads load evenly.
  3. Avoids hot partitions.
  4. Keeps transactions local.
  5. Has stable ownership.

Bad shard keys create expensive scatter-gather queries.


Rebalancing

Eventually, shards become uneven or you need more capacity. Rebalancing moves data.

ApproachNotes
Consistent hashingReduces movement when adding nodes
Virtual shardsMany logical shards mapped to fewer physical nodes
Live migrationCopy data while serving traffic, then cut over
Dual writesTemporarily write to old and new locations

Rebalancing needs observability, backpressure, and rollback. It is a distributed systems project, not a quick schema change.


Materialized Views and Denormalization

Sometimes the best scaling move is to precompute expensive reads.

PatternBest ForTrade-off
Materialized viewExpensive aggregate queriesRefresh complexity
Denormalized tableFast read modelWrite amplification
Search indexText and faceted searchEventually consistent
Analytics storeOLAP queriesData pipeline complexity

Use read models when product queries are stable and expensive to compute repeatedly.


Connection Pooling

Databases cannot handle unlimited connections. Each connection consumes memory and scheduling overhead.

Pooling Problems at Scale

ProblemFix
Too many app instances create too many connectionsUse PgBouncer, ProxySQL, or managed poolers
Long transactions hold connectionsKeep transactions short
Pool too smallRequests queue in app
Pool too largeDatabase thrashes
Serverless burst opens many connectionsUse pooler or data API

Pool size should be based on database capacity and query duration, not on arbitrary defaults.


Query Optimization

Query Plan Basics

Practical Rules

  1. Use EXPLAIN or EXPLAIN ANALYZE.
  2. Add indexes for common filters, joins, and ordering.
  3. Avoid SELECT * on hot paths.
  4. Paginate with stable keys for large lists.
  5. Watch N+1 query patterns.
  6. Archive cold data when tables grow huge.
  7. Track slow queries continuously.

Index Trade-offs

BenefitCost
Faster readsSlower writes
Faster sortingMore disk
Better joinsMore maintenance
Unique constraintsPotential write contention

What to Remember for Interviews

  1. Measure before scaling: know whether the bottleneck is reads, writes, locks, CPU, IO, or connections.
  2. Read replicas scale reads: but introduce replica lag.
  3. Sharding scales writes: but complicates queries, transactions, and rebalancing.
  4. Precompute expensive reads: materialized views and denormalization trade write complexity for read speed.
  5. Connection pools protect databases: uncontrolled connections can take down a system.

Practice: Design database scaling for an order-history page with 100 million orders, read-heavy traffic, occasional writes, and enterprise tenant isolation.