Menu

Earn Premium with Referrals

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

See how it works and start inviting friends.

Write-Behind
HLD

Write-Behind

Write to cache now, storage later — absorbing write storms at the risk of loss, bounded by flushing discipline.

The Pattern

 WRITE:  ack immediately after CACHE accepts; db update ASYNC

 app ──write──► [ cache ] ──ack──► caller (fast!)

                    └── buffered queue ──► batch flush ──► [ db ]
                              (every N sec / M entries)

 READS: always served from cache → fast AND fresh
 
 aka WRITE-BACK. the queue between cache and storage is
 the entire design problem.

What It Buys

 ✓ write latency = cache speed alone (~1ms, no db hop)
 ✓ write BURSTS absorbed by buffer; db sees steady batches
   (queue-based load leveling, built into your writes)
 ✓ batching cuts db load: 1000 updates → few bulk upserts
 ✓ db outages tolerated briefly (writes queue while it's down)

 classic homes: like counters, view counts, presence hearts,
 game score updates — hot counters that would melt a row
 lock if written synchronously per event.

The Price: Loss Window

 cache node dies before flush → those writes are GONE.

 uncommitted window = flush interval × failure probability

 engineering the window down:
 - short flush intervals (1–5s typical)
 - replicate the buffer itself (redis replication/AOF)
 - journal writes to disk BEFORE ack (WAL-in-cache)
 - accept loss for THIS data class (likes ≠ payments)

 decision rule: "is losing ≤5s of these writes acceptable?"
 NO → write-through/aside instead. this pattern is only for
 data whose loss is annoying, never catastrophic.

Consistency Complications

 - reads from OTHER paths hit the DB and see STALE data
   until flush → cross-system read-your-writes breaks
 - concurrent updates to same key need merge semantics
   (last-write-wins? increment? CRDT-ish?)
 - ordering: buffer must preserve per-key order
   or final state may be wrong even without loss

 document which external readers see stale data and how long;
 surprise staleness is how write-behind deployments die politically.

Flush Design

MechanismBehavior
Interval timerFlush every T seconds — predictable lag
Size thresholdFlush at M pending — bounds memory
HybridWhichever first — standard choice
Per-key coalescingCollapse repeated writes; flush last value
Incremental opsShip INCR deltas instead of absolute values

Coalescing matters enormously for counters: 500 likes in the interval become ONE +500 statement.

When It Fits

 ✓ high-rate mutable counters/stats with loss tolerance
 ✓ bursty writes against a fixed-capacity store
 ✗ money, inventory, anything audited
 ✗ when other systems read the db expecting freshness
 
 often implemented NOT as whole-database strategy but as a
 targeted counter-service: redis + periodic flush job beside
 an otherwise conventional stack.

Interview Framing

“Count video views at 100k/s” is THE trigger question. Scored shape: write-behind with INCR in Redis, hybrid flush (2s/10k), coalescing math (“db sees ~1 write/sec per video”), explicit loss-window acceptance, and the boundary sentence — “payment writes stay synchronous.” That last line is what separates pattern knowledge from judgment.

My Private Notes

Notes are auto-saved locally to this device.