Distributed Systems Cheat Sheet

The problem says X → think Y, with the reason attached. Every right-hand column is a thought, never a product: “queue keeps growing → Kafka” is the reflex this domain exists to replace, and “your consumers are slower than your producers, so capacity, admission or priority must give” is something you can act on.

The problem saysThinkWhyLessons
Remote call timed outThe outcome is unknown, not failedThree of the five realities behind a timeout involve the work having completed. Treating it as failure is wrong more often than it is right.
A retry might duplicate the operationIdempotencyRetries are unavoidable, so duplicates are the tax. Make the second attempt harmless rather than trying to prevent it.
Need exactly one active ownerLease plus fencing tokenElection alone does not stop a paused old owner from acting. The resource must reject the stale token.
Two replicas disagreeConflict resolution, and a rule chosen in advanceDivergence is normal after a partition. What matters is whether your merge rule loses data silently.
Everyone must see the same orderTotal order broadcast — which means consensusTotal ordering and consensus are equivalent problems. That equivalence is why it is expensive.
Need writes to stay available under partitionWeaker coordination, plus reconciliationYou are choosing the A side of CAP for this operation. Decide what repairs the invariant afterwards.
Need more read throughputReplicas, with an explicit staleness policyRead scaling is cheap. The cost is that every read site now needs a decision about staleness.
Need more write throughput or storagePartitioningReplication does not scale writes — every replica does every write. Only partitioning divides the work.
One key gets enormous trafficHot key — and more partitions will not helpA single key lands on a single partition regardless of hash quality. Cache, split, replicate or coalesce.
Queue depth keeps growingBackpressure — consumers are slower than producersAn unbounded queue converts overload into latency collapse. Bound it and decide what to shed.
One dependency's outage takes down everythingContainment: bulkheads, breakers, timeoutsWithout isolation, a slow dependency consumes the caller's threads and the failure travels upstream.
Retry traffic is larger than real trafficBackoff, jitter and a retry budgetRetries at three tiers with three attempts each is 27x amplification. Cap retries as a fraction of original load.
A change must span two servicesSaga, or move it into one transactionAsk first whether the boundary is right. A cross-service transaction is often a misplaced service boundary.
A message may arrive twiceIdempotent consumerAt-least-once is what a network can offer. The consumer, not the broker, is where exactly-once effects are achieved.
Several systems need the same eventPub/sub, or a log if replay mattersIf a consumer added next year must see history, you need retention — a queue cannot provide it.
Need to reprocess historyA durable, retained event logReplay is a property of retention plus consumer-tracked offsets, not of any particular product.
Need ordering for a given entityPartition by that entity's keyOrdering is guaranteed within a partition. Keying by entity is how you buy per-entity ordering.
Need something globally uniqueCoordination, or partitioned ownershipEither one node decides, or the decision is serialized. There is no third option that is also cheap.
Writes in two regions conflictA write model chosen deliberatelySingle-writer, multi-writer and partitioned ownership have very different conflict and latency profiles.
All replicas are in one zoneCorrelated failure — you have one failure domainThree replicas that fail together are one replica with extra cost. Independence is the property, not the count.
Log timestamps from two nodes disagreeCausal ordering, not wall-clock sortingClock skew means you cannot sort a distributed log by timestamp. Correlate by trace id instead.
A user does not see their own writeRead-your-writesThe narrow guarantee fixes the visible bug far more cheaply than global consistency would.
Fan-out request is slow but each shard is fastTail latency at scaleWith 100 shards each 1% slow, the chance at least one is slow is 63%. Component tail becomes aggregate median.
The search index disagrees with the databaseDerived state needs reconciliationDecide which is authoritative, then build the repair path. Drift is expected, not exceptional.
Services must all deploy togetherDistributed monolithYou are paying every distributed cost and getting no autonomy. The boundary is in the wrong place.
An agent retried and charged twiceAgent idempotencyA model retrying an unacknowledged tool call is the timeout-ambiguity case. Side-effecting tools need keys.

26 of 26 rows shown. A row is a starting thought, not a design. Every one of them ends in the same two questions: what guarantee does this need, stated precisely enough to test — and what does each node actually know when it decides?