Menu

Earn Premium with Referrals

Invite your friends and earn Premium rewards through our referral program.

See how it works and start inviting friends.

Database QPS Ceilings
HLD

Database QPS Ceilings

What one database node can actually serve — read/write asymmetry, connection limits, and the numbers that trigger scaling moves.

The Numbers That Decide When to Scale

Order-of-magnitude ceilings for a single well-configured node (illustrative; workload-dependent):

 RELATIONAL (Postgres/MySQL class), single primary:
   reads  via indexes:    ~5,000–50,000 qps   (cached pages, simple queries)
   writes:                ~1,000–10,000 wps   (fsync-bound; group commit helps)
   complex joins/aggregates: hundreds         (each query is heavy)

 IN-MEMORY (Redis class), single node:
   simple GET/SET:        ~100,000+ ops/sec
   with Lua/pipelining:   multiples more

 DOCUMENT/wide-column nodes: thousands per node, scale by adding nodes

The write ceiling is the architecturally important one: reads replicate; writes have exactly one owner in classic setups. Every scaling story eventually collides with a write wall.

Why Reads and Writes Differ So Much

 READ path:  index lookup → buffer pool (RAM) → return
             no durability ceremony; replicas add parallel capacity
 
 WRITE path: log WAL → fsync (disk latency!) → update pages → commit
             fsync ≈ sub-ms SSD but non-negotiable for durability
             every index on the table = extra write work
 
 5 indexes on a hot table can make one INSERT cost ~3–4x internally

This is why read scaling (replicas + cache) is cheap and write scaling (sharding) is a project.

Connection Limits — The Silent Ceiling

Databases die of connections before they die of QPS:

 each backend connection costs memory (~MBs) in the DB

 app nodes × pool size vs DB max:
   16 app nodes × 20 conns = 320        fine under ~500 limit
   
 at 40 app nodes: 800 conns            DB thrashing territory
 → fix: pooler/proxy (pgbouncer-class) multiplexing many→few
 → this is why "just add app servers" breaks databases quietly

Capacity plans must include the connection equation, not just QPS.

Replication Changes the Read Math Only

 1 primary + 5 replicas ≈ 6x read capacity (minus lag effects)
 write capacity: UNCHANGED — still one primary absorbing everything
 
 replication lag adds its own number: async replicas trail by
 milliseconds (same region) to seconds (cross-region)
 → read-after-write patterns must respect this (session pinning)

Using These Numbers in Design

RideShare check:

 need: ~1,000 write-qps peak at data layer (trips + derived updates)
 single Postgres write ceiling: comfortably above it ✓
 verdict: primary + replicas now; shard design documented as the
          next-stage plan, triggered around sustained multi-thousand wps

One division against an honest ceiling produced the entire storage strategy.

Interview Framing

Candidates who quote ceilings get challenged (“where’s that from?”). Safe framing: ranges plus mechanism (“writes are fsync-bound so low-thousands; reads hit RAM so tens of thousands”). The follow-up almost always probes the connection math or replication-lag consequences — having both ready marks operational experience over memorization.

My Private Notes

Notes are auto-saved locally to this device.