What a machine boundary actually changes

Fundamentals

9 lessons. Every one names the guarantee it claims, what a node can know, and how it fails.

What Actually Makes a System Distributed▶ lab

Not the number of machines, and not the word "microservices". A system is distributed the moment its correctness depends on a component that can fail independently and whose state you can only learn about through messages that may be lost, delayed or reordered.

Q · When does my system stop being one program and start being a distributed system?

A Remote Call Is Not a Function Call▶ lab

The syntax is identical and the semantics are not. A local call either returns or throws; a remote call has a third outcome — no answer — and that outcome carries no information about whether the work was done. Everything else follows from that.

Q · My RPC client makes a remote call look exactly like a local one. What is that hiding?

The Network Changes Everything▶ lab

A network can lose a message, delay it arbitrarily, deliver it out of order, deliver it twice, or partition the cluster into groups that each think the other side is gone. Those five behaviours are not edge cases to handle later — they are the design input.

Q · What exactly does the network do to my messages, and which of it can I stop worrying about?

No Shared Memory: Every Node Sees a Copy▶ lab

Two threads can read the same bytes. Two nodes never can. Each holds a copy whose age is the time since the last message, which means "the current value" is not a thing either node can observe — only a thing they can agree to pretend about, at a price.

Q · Why can I not just read the other service’s state the way I read a variable?

There Is No Global Clock▶ lab

Two machines cannot agree on what time it is closely enough to order events by timestamp. Which means a comparison of two timestamps from two hosts is not an ordering — it is a guess, and it is wrong in exactly the cases you built it to handle.

Q · Why can I not just compare timestamps to work out which event happened first?

Why Distribute At All▶ lab

There are exactly four reasons that survive scrutiny: the work does not fit on one machine, one machine failing is unacceptable, users are far away, or components must be isolated from each other. Everything else on the usual list is one of these four wearing a costume.

Q · What problem am I actually solving by putting this on more than one machine?

When Not to Distribute▶ lab

Most systems that adopt distribution do not need it. The costs — partial failure, ambiguity, operational surface, debugging across boundaries — are paid on day one and every day after. The benefits are conditional on assumptions that frequently turn out to be false.

Q · What is the honest case for keeping this on one machine?

Where the Boundary Goes▶ lab

A boundary is not a line on a diagram. It is the place where shared memory ends, where partial failure enters, and where an invariant stops being enforceable by the compiler. Choose it by asking which state must never disagree — not by which nouns look separate.

Q · If I am going to split this, where exactly should the cut go?

Name the Invariant Before You Choose the Protocol▶ lab

Every coordination decision in a distributed system is downstream of a single question: what must never be false? Teams that cannot state their invariants precisely end up coordinating everywhere, which is slow, or nowhere, which is wrong.

Q · How do I decide which parts of my system actually need agreement?