The same problems, one network hop away
Everything in this roadmap so far has assumed one process, one address space: a mutex works because every thread can see the same memory. The moment your "critical section" spans two servers, that assumption breaks — there's no shared memory for a mutex to live in, and messages between machines can be delayed, dropped, duplicated, or reordered in ways a single process's scheduler never does to you. This subtopic is intentionally brief: full distributed-systems theory (consensus, replication, CAP trade-offs) is its own discipline, out of scope here. The goal is narrower and more honest — see that the concepts you already know generalize, learn the couple of tools that replace your in-process primitives, and have enough to say something credible if an interview drifts this direction, without pretending this page makes you a distributed-systems expert.
Mutual exclusion becomes a distributed lock
An in-process mutex is trivial to implement correctly because the OS guarantees only one thread executes the critical section at a time. Across machines, the closest equivalent is a distributed lock — typically built on a shared store like Redis, or a consensus-backed service like ZooKeeper or etcd — where "acquiring the lock" means successfully writing a key that only one client can hold at a time (e.g., Redis's SET key value NX PX ttl, which sets a key only if it doesn't already exist, with an expiry so a crashed holder doesn't lock everyone out forever).
The catch, and the thing worth actually knowing rather than just name-dropping: a single-Redis-node lock has a single point of failure, so Redis's own documentation proposes Redlock — acquiring the same lock across a majority of independent Redis nodes to tolerate one node failing. Martin Kleppmann's well-known critique of Redlock is worth knowing about specifically because it's such a good illustration of why distributed correctness is harder than it looks: Redlock's safety depends on assumptions (bounded clock drift, bounded pauses) that don't reliably hold in practice — a long GC pause or network delay can let a client believe it still holds a lock after another client has already acquired it. Kleppmann's fix is a fencing token: a monotonically increasing number handed out with every lock acquisition, which the protected resource itself checks and rejects if it's ever presented with a token lower than one it's already seen. The uncomfortable but important detail: fencing only works if the resource being protected enforces it — the lock service alone can't guarantee it.
Atomic compare-and-swap becomes an idempotency key
In-process, "do this exactly once even under concurrent retries" is a CAS loop or a lock (Topic 7). Across a network, the extra failure mode is that a client can't always tell whether a request it sent actually succeeded — the request might have been processed and only the response got lost, in which case a naive retry duplicates the operation (charging a customer twice is the textbook example). The standard fix is an idempotency key: the client generates a unique ID up front and attaches it to the request; the server records the outcome keyed by that ID, and if the same key shows up again — because of a client-side retry — it returns the original result instead of redoing the work. Stripe's API is the widely-cited reference implementation of this pattern (an Idempotency-Key header on every mutating request), and it's worth understanding as "atomicity, but implemented by deduplicating retries at the server rather than by any kind of lock."
What to say if this comes up in an interview
You're not expected to design a consensus protocol live. A credible answer sounds like: "in-process I'd reach for a mutex; across services, a distributed lock via Redis or ZooKeeper for coordination, plus idempotency keys for retry-safety — and if correctness genuinely depends on the lock rather than it being an optimization, I'd want a consensus-backed service with fencing tokens over bare Redlock." That sentence shows you know how single-machine concepts map onto their distributed analogues, which is this subtopic's actual point — go deeper into distributed systems proper (Kleppmann's Designing Data-Intensive Applications is the standard next stop) if that's where your next loop is headed.