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 says | Think | Why | Lessons |
|---|---|---|---|
| Remote call timed out | The outcome is unknown, not failed | Three 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 operation | Idempotency | Retries are unavoidable, so duplicates are the tax. Make the second attempt harmless rather than trying to prevent it. | |
| Need exactly one active owner | Lease plus fencing token | Election alone does not stop a paused old owner from acting. The resource must reject the stale token. | |
| Two replicas disagree | Conflict resolution, and a rule chosen in advance | Divergence is normal after a partition. What matters is whether your merge rule loses data silently. | |
| Everyone must see the same order | Total order broadcast — which means consensus | Total ordering and consensus are equivalent problems. That equivalence is why it is expensive. | |
| Need writes to stay available under partition | Weaker coordination, plus reconciliation | You are choosing the A side of CAP for this operation. Decide what repairs the invariant afterwards. | |
| Need more read throughput | Replicas, with an explicit staleness policy | Read scaling is cheap. The cost is that every read site now needs a decision about staleness. | |
| Need more write throughput or storage | Partitioning | Replication does not scale writes — every replica does every write. Only partitioning divides the work. | |
| One key gets enormous traffic | Hot key — and more partitions will not help | A single key lands on a single partition regardless of hash quality. Cache, split, replicate or coalesce. | |
| Queue depth keeps growing | Backpressure — consumers are slower than producers | An unbounded queue converts overload into latency collapse. Bound it and decide what to shed. | |
| One dependency's outage takes down everything | Containment: bulkheads, breakers, timeouts | Without isolation, a slow dependency consumes the caller's threads and the failure travels upstream. | |
| Retry traffic is larger than real traffic | Backoff, jitter and a retry budget | Retries at three tiers with three attempts each is 27x amplification. Cap retries as a fraction of original load. | |
| A change must span two services | Saga, or move it into one transaction | Ask first whether the boundary is right. A cross-service transaction is often a misplaced service boundary. | |
| A message may arrive twice | Idempotent consumer | At-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 event | Pub/sub, or a log if replay matters | If a consumer added next year must see history, you need retention — a queue cannot provide it. | |
| Need to reprocess history | A durable, retained event log | Replay is a property of retention plus consumer-tracked offsets, not of any particular product. | |
| Need ordering for a given entity | Partition by that entity's key | Ordering is guaranteed within a partition. Keying by entity is how you buy per-entity ordering. | |
| Need something globally unique | Coordination, or partitioned ownership | Either one node decides, or the decision is serialized. There is no third option that is also cheap. | |
| Writes in two regions conflict | A write model chosen deliberately | Single-writer, multi-writer and partitioned ownership have very different conflict and latency profiles. | |
| All replicas are in one zone | Correlated failure — you have one failure domain | Three replicas that fail together are one replica with extra cost. Independence is the property, not the count. | |
| Log timestamps from two nodes disagree | Causal ordering, not wall-clock sorting | Clock skew means you cannot sort a distributed log by timestamp. Correlate by trace id instead. | |
| A user does not see their own write | Read-your-writes | The narrow guarantee fixes the visible bug far more cheaply than global consistency would. | |
| Fan-out request is slow but each shard is fast | Tail latency at scale | With 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 database | Derived state needs reconciliation | Decide which is authoritative, then build the repair path. Drift is expected, not exceptional. | |
| Services must all deploy together | Distributed monolith | You are paying every distributed cost and getting no autonomy. The boundary is in the wrong place. | |
| An agent retried and charged twice | Agent idempotency | A 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?