Failure Scenarios & Scaling
How each architectural layer fails, how the system degrades gracefully, and what happens when load increases beyond expected limits. The scenarios are constructed for teaching, not documented incidents.
CDN Degradation
CDN edge nodes become unreachable. Media requests fall through toward origin.
CDN failures are typically partial — individual PoPs or regions fail, not the entire network. Affected users experience degraded media load times. Text-based feed metadata remains available and fast, since it does not depend on the CDN.
Origin object storage sees a spike in direct requests. Origin should be sized to absorb a reasonable percentage of CDN-bypass traffic as a burst — not the full scale of normal CDN traffic, which would be prohibitively expensive to provision for. Rate limiting at the origin protects it from complete saturation at the cost of some requests being rejected during the worst of the degradation.
Feed Store Failure
The pre-computed feed store becomes unavailable. The Feed Service must degrade rather than simply falling back to unrestricted read-time composition for every request.
Naively falling back to full fanout-on-read for every single request during an outage simply recreates the original database-load problem that the feed store existed to solve — at exactly the moment the system is already degraded. A better approach is bounded degradation: serve cached or slightly stale feeds where available, reduce the candidate count considered per request, simplify or skip expensive ranking, allow controlled (rate-limited) read-time composition rather than unlimited fallback, and apply load shedding to protect the database from being overwhelmed.
A circuit breaker around the feed store prevents repeated failed calls from adding latency once the failure is detected, and helps the system shift cleanly into the degraded mode described above rather than retrying the same failing path per request.
Media Processing Backlog
A major event causes uploads to spike well beyond normal processing capacity.
The processing queue's lag grows, and posts sit in PROCESSING for longer than usual. Worker autoscaling can help, but it is ultimately bounded by downstream CPU/GPU and storage constraints — transcoding is genuinely expensive work, and there is a real ceiling on how fast it can scale.
Users see their own posts remain visibly in a PROCESSING state for longer than usual rather than a hard failure. Prioritization and fairness matter here just as they do for fanout: a handful of large uploads should not be allowed to starve the processing of many smaller, ordinary ones. A backlog-age SLO (e.g., a target maximum time in PROCESSING) gives the system something concrete to recover toward, and recovery should ramp back to normal capacity gradually rather than causing a second spike.
Corrupt / Poison Media
An uploaded file is corrupt, malformed, or otherwise unprocessable.
Validation at completion time (file size/type checks, integrity checksum) catches many cases immediately. For cases that only fail during actual processing, transient issues should be retried a bounded number of times — not indefinitely. A file that keeps failing after those bounded retries is moved to a dead-letter or quarantine path and the post is marked FAILED, rather than being retried forever and silently consuming worker capacity.
Observability matters here: quarantined media should be inspectable so engineers can distinguish a genuinely corrupt file from a processing bug affecting many uploads at once.
Fanout Backlog / Partial Delivery
A large fanout job is still in progress when a reader opens their feed.
Because fanout batches followers and checkpoints progress, some followers may have already received the new feed entry while others have not — temporary partial visibility, resolved by eventual consistency as the remaining batches complete.
Retries against a partially completed job are safe because feed writes are idempotent: reprocessing an already-completed batch produces no duplicate entries. Fairness policies ensure this catch-up work does not indefinitely delay fanout for other, unrelated posts queued behind it.
Feed Store State Lost
The feed store's underlying data is lost outright — not just temporarily unavailable, but gone.
Because the feed store is derived state, posts themselves remain completely safe in the durable post store — nothing about this loses actual content. Recovery means rebuilding recent candidates from source data: for each affected user, reconstruct a recent feed by querying followed accounts' recent posts, rather than treating the loss as unrecoverable.
Rebuilding for every user at once would recreate the exact database-load problem fanout was built to avoid. Prioritize active users first, serve those users via temporary, rate-limited read-time composition while their feed store entry is being rebuilt, and rate-limit the rebuild work itself so it does not overwhelm the same database it's reading from.
Deleted/Private/Blocked Content Still in Feed
A post already fanned out to millions of feed stores is deleted — or the author blocks the reader, goes private, or is suspended after distribution.
This is a correctness question, not a performance failure. Correctness comes from read-time visibility validation during hydration — checking post availability and the current relationship/visibility state before the post is ever shown — not from synchronously rewriting every feed store entry that referenced it.
For media specifically, application-level unavailability can take effect immediately while CDN cache invalidation follows shortly after; either way, the removed content should not be served through the feed, even if a stale reference to it lingers in a feed store until asynchronous cleanup removes it.
Like Counter Hotspot
A viral post receives millions of likes in a short window.
If every like synchronously increments one relational counter row, that row becomes a write hotspot — every interaction serializes against the same row, and throughput is capped by how fast a single row can be updated, regardless of how much other capacity exists elsewhere in the system.
Partitioned/sharded counters split the increment load across multiple physical counters instead of one, removing the single-row bottleneck. A fast counter layer absorbs immediate writes and gives users instant feedback, while asynchronous aggregation periodically reconciles the sharded counters into a durable total. During this window, the displayed count may be a temporary, eventually-consistent approximation rather than an exact real-time figure — an acceptable trade-off for a like count.
| Scenario | First signal | Degraded mode |
|---|---|---|
| 01 Fanout workers unavailable | Queue lag (age of the oldest unprocessed fanout event) | Feeds go stale; posting continues |
| 02 CDN degradation | Media error rate and latency by PoP/region | Slower media; origin absorbs a bounded burst |
| 03 Feed store failure | Feed store error rate / circuit breaker opening | Bounded, rate-limited read-time composition |
| 04 Viral post / hot user | Read QPS and replica load on the post store; like-counter write rate | Replicas, caches and rate limiting absorb read amplification |
| 05 Media processing backlog | Processing queue lag; posts dwelling in PROCESSING | Explicit PROCESSING state; no hard failure |
| 06 Corrupt / poison media | Rising retry or quarantine counts for one upload or a class of uploads | Bounded retries, then quarantine |
| 07 Viral media, cold CDN | Shield hit ratio drop and origin request spike for one object | Shield tier and request coalescing |
| 08 Fanout backlog / partial delivery | Per-job fanout progress and lag | Temporary partial visibility, then idempotent completion |
| 09 Social graph unavailable | Graph-lookup error rate; fanout events waiting to retry | New fanout and pull-source discovery pause; computed feeds still serve |
| 10 Ranking slow or unavailable | Ranking latency against its budget; fallback rate | Cached ranked results, heuristic or chronological order |
| 11 Feed store state lost | Missing or empty feeds for active users | Prioritised, rate-limited rebuild from source data |
| 12 Deleted/private/blocked content in feed | Read-time visibility filter hit rate; async cleanup backlog | Hydration-time filtering keeps removed content out of feeds |
| 13 Like counter hotspot | Write latency or contention on a single counter | Sharded counters with asynchronous aggregation |
Social Graph Unavailable
The Social Graph service becomes unavailable.
Posting and media processing can continue as long as their own storage is healthy — they do not depend on the social graph directly. Fanout, however, cannot enumerate a poster's followers and must queue the fanout event and retry rather than fail outright, resuming once the graph service recovers.
Existing, already-fanned-out feed entries in the feed store can continue serving candidates normally — that data does not require a live graph lookup to read. Pull-source discovery for high-fanout accounts, however, needs a following-lookup at read time; this can fall back to cached graph state if available, or degrade to serving only precomputed candidates while the graph service is down.