TRT
Sign in
System DesignUpdated

What Is a Distributed System, Really?

A system where the failure of a computer you didn't even know existed can render your own computer unusable. How to recognize a distributed system you never asked for.

The Runtime Theory Team8 min read#distributed-systems#consensus#replication#fallacies

The canonical definition of a distributed system — Leslie Lamport's — is a one-liner with more engineering in it than most textbooks:

A distributed system is one in which the failure of a computer you didn't even know existed can render your own computer unusable.

Read it again, because the point is not about multi-machine complexity. It is about compounding independence: every machine gets its own clock, its own opinion about ordering, its own failure modes — and none of them owes you a heads-up. The phrase "distributed" is not a deployment choice; it's a physics that enters the moment a second clock exists.

The fallacies that pre-wire the failures

The "Eight Fallacies of Distributed Computing" were coined in the 1990s at Sun and have aged exactly as well as physics predictions: they're all still true.

FallacyThe reality
the network is reliablepackets are lost, delayed, duplicated, reordered — constantly
latency is zeroevery hop costs real, variable, queueable time
bandwidth is infinitea saturated link is a queue with a queue
the network is secureevery node is a trust boundary with its own enemies
topology doesn't changereleases, scale-ups, and failovers reshape the graph live
there is one administratorthere are N owners, N on-call rotations, N change windows
transport cost is zeroserialization + crypto + TCP machinery are real CPU
the network is homogeneousevery hop can speak a slightly different dialect (proxies, TLS, timeouts)

Every architectural debate that "has no answer" is usually here: the fallacies are the hidden specs of your system. Retry policies, timeouts, and queueing are all responses to "the network is reliable?", dressed in configuration.

The two clocks that break everything

Two physics problems appear the instant distance does:

1. Ordering. Two machines — no shared clock — must agree whether a happened before b. Lamport's clocks (and vector clocks after them) proved that ordering can only be partial: you can only know the order of events that causally affect each other. The entire industry's "eventual consistency" exists because total ordering is unachievable without a single authority — and a single authority is a single point of failure.

2. Timeouts. A machine cannot distinguish "the other side is slow" from "the other side is dead except not" — the indistinguishable pair that every timeout-based protocol must design around. This is exactly why consensus algorithms (Paxos, Raft) don't ask "is the leader alive?" but "who can still talk to a majority?" — the only question a split brain can answer safely.

When exactly did you build one?

The most honest symptom list, in little code:

text
you have a database
  ├─ replication?        → you designed for lag, conflicts, failover — briefly
  └─ connection pooling? → you designed against transient unavailability
you have a queue
  ├─ at-least-once?      → your consumer is built for duplicates
  └─ exactly-once?       → congratulations; you've built consensus
you have caches
  └─ invalidation        → you've built a *consistency protocol* without a proof

If any of those lines is "we assumed it works", you have a distributed system whose specs were written by hope. The honest engineering response is not "add Kubernetes" — it is to label the protocol you already run: which consistency model, which delivery guarantee, what happens to a message processed twice.

The two theorems that set the price

Two results set the boundaries of everything distributed, and they're worth quoting because they're limits, not opinions:

CAP. You can't have all three of consistency, availability, and partition-tolerance — and since partitions are physical, you choose between C and A during partitions. The real engineering question isn't "which of CAP do I pick?" (everyone picks "available when possible, consistent when possible") — it's what happens during the partition: do reads return stale data (eventual), or fail (strict)?

FLP. In an asynchronous system, no consensus protocol is guaranteed to terminate — for real systems, that's why we use timeouts and why those timeouts occasionally make the "wrong" decisions. It is also why "exactly once delivery" is a marketing term in every distributed story: you can get at-least-once plus deduplication, and the map between them is the hard part.

The mindset that fixes most of it

Good distributed engineers write their systems' failure budget inventories: a one-page table of every component, its delivery/consistency guarantee, what happens under timeout, and who owns the retry. Teams that can't fill in the "timeout" column are not distributed engineers — they're people with a deployed distributed system.

That inventory is also the platform's whole philosophy in miniature: not "how do I use the tool" but "what actually happens when it fails — and what did we choose to happen instead?"

Production cost model and latency numbers

To apply What Is a Distributed System, Really? effectively in production systems, engineers must move beyond qualitative diagrams and quantify the exact hardware and network costs at each boundary:

Operation / BoundaryTypical LatencyDominant BottleneckProduction Mitigation
L1 / L2 Cache Access1 ns – 4 nsRegister dependency chains & pointer chasingContiguous memory layouts, cache-line alignment (64 B), and batch iteration
Main Memory (DRAM) Fetch60 ns – 100 nsTLB misses, random heap indirection, NUMA hopsHugePages (2 MB), arena/slab allocators, and pre-allocated ring buffers
Kernel Syscall / Context Switch1 µs – 5 µsUser-to-kernel mode switch, page-table flush, lock contentionNon-blocking readiness loops (epoll / io_uring), batching, and zero-copy I/O
NVMe SSD Random Read / fsync50 µs – 500 µsBlock I/O queue depth, write amplification, WAL flushesGroup commit, sequential append logs, and bounded buffer-pool pinning
Intra-Region RPC Roundtrip0.5 ms – 2.5 msSerialization, TCP/TLS framing, tail queueing ($L = \lambda W$)Connection pooling, deadline propagation, and p95 hedged requests

Failure modes, debugging, and operational checklist

In real incidents, systems rarely fail at average (p50) load—they fail when a slow dependency, skewed hot key, or resource leak pushes concurrency across a non-linear saturation cliff. When reviewing code or architecture that relies on What Is a Distributed System, Really?, walk through three verification questions:

  1. What is the invariant under partial failure or contention? If a worker crashes mid-operation, a network packet is delayed and reordered, or two threads race on the same state transition, prove which atomic primitive, version number, or idempotency key prevents silent corruption.
  2. How is backpressure enforced when demand exceeds capacity? Unbounded in-memory queues, unthrottled retries, and blocking calls without explicit deadlines turn a localized 100 ms slowdown into a fleet-wide Out-Of-Memory (OOM) cascade. Always bound queue depths, propagate caller deadlines, and shed excess load early.
  3. Which metrics and traces isolate the bottleneck in under 60 seconds? Instrument saturation, queue wait time vs service execution time, cache hit/miss ratios, and error rates by failure reason so on-call engineers can immediately distinguish a compute bottleneck from an I/O or lock-contention stall.

Spotted a mistake or something broken? Report a problem

Not started

Sign in to save your learning progress.

Sign in to save