DBAtlas · Database operations atlas

Reference Architecture: high scale / high traffic

As traffic grows, there is a right order for protecting the database: first the simple, cheap levers, then the complex ones. This tree walks step by step through the vertical scaling → read replica → sharding order, caching patterns (cache-aside, write-back), buffering with a queue + backpressure, rate limiting, isolating the database with bulkheads/circuit breakers, and preventing hot spots. Core principle: leave hard-to-reverse decisions such as sharding for last, and exhaust the cheap wins first.

Where is the bottleneck: is a single instance saturated, are reads or writes heavy, or is traffic bursty?

To solve a scaling problem in the right place, first identify the bottleneck. Is a single instance saturated on CPU/memory, are reads dominant, are writes hitting the limit, or are sudden traffic spikes crushing the database? Each points to a different component.

  • A single instance is saturated; I have not tried the simple levers yet
  • Reads are very heavy and growing
  • Sudden traffic spikes / bursty load are crushing the DB

Which scaling step are you at: vertical, read replicas or sharding?

Scaling has a right order. Vertical scaling (more powerful hardware) is the simplest first step; then you spread reads across replicas; only when a single primary can no longer handle the writes do you move to horizontal partitioning (sharding). Where are you?

  • I have not scaled up the hardware / exhausted the basic tuning yet
  • Writes fit on one instance, but I need to spread the read load
  • A single primary can no longer handle the write load

How will you protect the database from load: buffering, limiting or isolation?

Scaling is not always about making the DB bigger; often it is about protecting the DB from overload. Will you smooth sudden write spikes with a queue, limit the incoming request rate (rate limiting), or prevent a single dependency from bringing down the whole system (bulkhead/circuit breaker)?

  • I want to smooth out sudden write spikes
  • I want to limit/fairly share the incoming request rate
  • I do not want one failing dependency to take down the whole system

Recommendation: vertical scaling and basic tuning first

The cheapest and least risky step is vertical scaling: adding more CPU/RAM/faster disks and fixing the basics (indexes, connection pooling, memory parameters). Exhaust these wins before complex decisions such as sharding.

Recommendation: spread reads with read replicas

Writes stay on a single primary while read-only traffic is spread across one or more replicas. It is much simpler than sharding and solves most read-heavy workloads; the primary remains only for writes and consistency-critical reads.

Recommendation: sharding (horizontal partitioning) as a last resort

When a single primary cannot handle the write load, you split the data by a key into multiple independent pieces (shards); each shard takes on part of the writes. It is powerful but hard to reverse; it complicates cross-shard queries and transactions, so it is left for last.

Recommendation: caching patterns (cache-aside + write-back)

With read-heavy high traffic, you put an in-memory cache (Redis) in front of the DB and serve most reads without them ever reaching the DB. For high-volume writes, write-back buffers writes and flushes them to the DB in batches, relieving the primary.

Recommendation: buffering with a queue (backpressure)

To keep sudden write spikes from hitting the DB directly, you put a durable queue (e.g. Kafka/a message queue) in between and consume writes at the rate the DB can sustain. The queue absorbs the spike; instead of failing synchronously, the system runs with controlled latency (backpressure).

Recommendation: rate limiting (limit the request rate)

By limiting incoming requests per source (rate limiting), you prevent both abuse and a single client consuming all resources. Capping the load that reaches the DB keeps the system predictable and fair.

Recommendation: bulkhead + circuit breaker (isolation)

To prevent a dependency (e.g. a slowing DB or an external service) from bringing down the whole system, you partition resources into compartments (bulkheads) and temporarily cut calls to a dependency that keeps failing (circuit breaker). This way a partial failure does not spread to the whole system.

Open in DBAtlas →