Correct Parts, Broken Whole
Why race conditions prove that individual correctness isn't enough
You text your partner: we’re out of milk, can you grab some on the way home?. No reply comes back because they’re already standing in the checkout line with a gallon in hand, having opened the same empty carton that morning. That night the refrigerator holds two gallons, and neither of you did a single thing wrong. You both noticed. You both acted. The only trouble was that you acted at the same time, each of you certain you were the only one moving.
Engineers have a name for this, borrowed from the machines they build, and once you have it you start seeing it in places that have nothing to do with milk. A race condition is what you get when the outcome of a situation depends less on what each party does than on the order and timing in which they do it, with nobody in charge of the order. Two actions, each correct on its own, collide because they reached for the same thing at the same moment. The failure lives in the gap between them. Each action, examined alone, is flawless.
Three things have to line up for a race. There has to be something shared, a fridge or a bank balance, that more than one party can change. There have to be at least two of them acting. And there has to be a gap, however small, between the moment someone checks the shared thing and the moment they act on what they saw. In that gap, the world can move. You glance at the carton, see it’s empty, and head for the store. Between your glance and your purchase, your partner’s glance and purchase have already happened. You acted on a fact that had quietly gone stale.
Most of us walk around with a silent assumption that we’re the only one touching whatever we’re looking at. Almost always it’s close enough to true, and life proceeds. The value of the phrase is that it names the exact circumstance where the assumption breaks, so you can feel the little flicker of danger before it costs you.
Born in the wiring
The term came from people who build circuits. In his 1954 doctoral thesis on sequential switching circuits, the engineer David Huffman was already using it for a specific hazard inside logic gates. Picture one electrical signal that splits and travels to a gate along two different paths, one a little longer than the other. The gate’s answer is supposed to depend only on the values of the signals, never on when they show up. But the two copies don’t arrive together, and for a few billionths of a second the gate sees a combination that should never exist and throws off a brief, wrong flicker. The signals are, quite literally, racing, and the circuit’s correctness hangs on which one wins.
When computers began doing many things at once, the same hazard climbed up out of the wires into the software, and the name climbed with it. Two programs, or two parts of one program, would both read a value, both decide what to do based on it, and both write back, and each one erased the other’s work. The textbook case is a bank account. Two withdrawals of a hundred dollars land at nearly the same instant. Each reads the balance, sees five hundred, subtracts a hundred, and writes back four hundred. Two hundred dollars left the account and the ledger recorded only one of the withdrawals. The account is now wrong, and no single line of code is to blame.
When the gap turns deadly
This stayed an abstraction you could file under engineering problems until the stakes got real. Between 1985 and 1987, a radiation-therapy machine called the Therac-25 delivered massive overdoses to cancer patients, and the software-safety researcher Nancy Leveson, who spent years reconstructing what went wrong, traced the core failure to a race condition. When an operator typed the treatment settings fast enough, two parts of the software fell out of step: a safety check ran against data that a quick edit had already changed, and the machine fired an unshielded beam hundreds of times stronger than intended. At least three people died. The individual pieces of that program mostly worked. What killed patients was the timing between them.
The same shape took down the power grid. On an August afternoon in 2003, a race condition in the alarm software running FirstEnergy’s Ohio control room, a system built by General Electric, silently stalled. Operators lost their warnings without knowing they’d lost them, a local line failure they couldn’t see cascaded outward, and by nightfall fifty-five million people across the American Northeast and parts of Canada had no electricity. The bug had probably been sitting in that code for years, harmless, waiting for two events to line up in exactly the wrong order.
The lesson underneath these disasters is an uncomfortable one because it undercuts how we usually decide whether something works. We check the parts. We make sure each function and each person does the right thing in isolation, and we conclude the whole is sound. Race conditions are the proof that this isn’t enough. You can bolt correct parts into a broken system because the correctness of the pieces tells you nothing about what happens when two of them grab the same thing at the same time. Timing is a hidden input, and most of the time we forget to test it.
Back at your desk
You don’t run a power grid, but you live inside small races all day. Two people on a team reply to the same customer, each assuming the other hadn’t gotten to it. A colleague and you both edit the same shared doc in the same five minutes, and one save quietly swallows the other’s paragraph. Worst is the inverse race, where a task falls through the floor because each of you checked, figured the other might be on it, and stepped back. “I thought you had it.” “I thought you did.” Nobody acted, for the very same reason that, with the milk, both of you did.
It gets sharper the moment you start working with AI because now you’re spinning up actors faster than you can keep track of them. You open two chats and point both at the same file. You set an agent running in the background while you keep working in the foreground, and both reach for the same document. You drop a half-finished draft into a model, get pulled away, and later paste it into a fresh session, and now two versions of the same piece are drifting apart in two tabs. Each session is doing exactly what you told it. The collision comes from the fact that you lost count of how many were running. This is the concurrent twin of the problem that makes idempotency matter: there, one actor sends the same instruction twice; here, two actors send correct instructions at once.
The engineers who tamed this didn’t do it by making each actor smarter. They did it by controlling the one thing that actually causes the damage: access to the shared object. Sometimes that means a lock, a way of saying “I’m working on this, everyone else wait,” so the actions line up in a queue instead of a pileup. Sometimes it means naming a single owner, so there’s only ever one hand on the thing at a time. The human version costs nothing and works the same way. Before you act on something more than one person can touch, say out loud who’s got it. “I’ll take the customer reply.” “I’m grabbing milk on the way home.” “I’ve got the doc for the next hour.” A sentence like that turns a race into a line, and the double gallon and the erased paragraph stop happening. You were never going to control the timing. What you can settle, in advance, is who goes first.


