Viral Counter Buffering Lab (Interactive)
Buffer a like flood and flush on an interval, turning a write storm into a few writes/sec. Contrast buffered aggregate flushes against direct per-event writes to a hot counter row under a like flood.
Instagram Likes at 100k/sec: Row-Lock Contention vs Write-Buffing
One celebrity post, one hot row. Count how many database transactions the like storm actually needs.
› INCR likes:{post_id} absorbed in Redis DRAM at 100,000/s; flush worker issues 1 UPDATE … SET likes_count = likes_count + N every 5s.
› A crash between flushes loses at most 500,000 increments (acceptable for vanity metrics, never for money — see double-entry ledger).
The same platform splits media (S3 + presigned PUT + async WebP workers), the follow graph (sharded by follower_id, Redis SETs for is-following checks), and counters. Write-back buffering turns the topic's example — 48,200 individual row transactions — into a single bulk update per window. Reads of "did I like this?" hit Redis sets; the DB remains the durable, eventually-consistent source.
How It Works Under the Hood
When a post goes viral, 50k likes/sec would each become an UPDATE on one counter row, so the row lock queues behind itself and the database melts. The fix is to buffer counts in memory or Redis and flush an aggregate to the durable row every few seconds — turning 50k writes/sec into a handful of flushes regardless of like volume. The counter row only needs to be eventually exact, and reads can add the un-flushed in-memory delta for freshness. Set like rate and flush interval to watch writes/sec collapse, and compare buffered against the direct path where every like hammers the row and lock contention balloons toward 100%.
Core Architectural Principles
- Direct path: writes/sec equals likes/sec, all contending on one counter row lock.
- Buffered path: writes/sec equals an aggregate-flush floor plus ceil(10,000 / flush_interval), independent of like rate.
- Lock demand percent equals likes/sec times the per-update lock hold time; the direct path saturates quickly.
Diagnose the hot-row write bottleneck and answer with in-memory or Redis buffering and periodic aggregated flushes, since a like count is eventually consistent by nature. Explain read-your-writes via adding the unflushed delta, sharding counters into multiple rows and summing, and why you do not need a transaction per like. Quantifying the write reduction from 50k/sec down to flushes makes it concrete.
Buffered counting protects the database and scales to viral spikes but delays exact durable totals; direct writes are instantly correct yet melt under load.