Every network request takes time. Every interface has a choice about what to show the user during that time — and one of the two honest-sounding options is, on its own, a lie the interface tells with total confidence.
Send a message, then dial the network
Below is one chat thread, one Slider standing in for a bad network, and one Toggle standing in for two entire architectures.
Dial the latency up, send a message, and watch what each side of the Toggle actually shows you while the server has an opinion pending. One renders nothing until the round trip finishes. The other renders the message immediately, then quietly ticks it over once the round trip agrees.
Send one yourself
optimistic — watch the bubble
No messages yet — tap Send.
Perceived response
—
measured — tap to painted frame
Simulated network
600ms
dialed below
0ms3000ms
Predict
At what simulated latency does the pessimistic side start to feel broken?
Part I
The Latency Bench
One todo list, three architectures, two dials: how slow the network is, and how often it actually lies to you.
Add a task under each strategy and watch what happens when the dialed failure rate turns a bet sour. Pessimistic blocks the button and either confirms or openly refuses — never both a claim and a mistake at once. Optimistic renders the task instantly and, on a loss, visibly undoes it with a stated reason. Local-first also renders instantly, but never undoes anything at all: a failed sync just stays queued, because the local write was already the truth the moment you typed it.
The latency bench
add a task, then change the odds
No tasks yet — tap Add.
Nothing added yet.
Perceived response
—
measured — tap to painted frame
Actual round trip
700ms
dialed below
Rollbacks witnessed
0
undone, visibly
Still syncing
0
local-first — queued, never undone
Strategy
0ms3000ms
ReliableFlaky
“Perceived response” is measured, not modelled — tap to painted frame, via two nested requestAnimationFrame calls, the same technique micro-interactions uses for its feedback-latency readout. “Rollbacks witnessed” and “Still syncing” are real counts from this session’s own seeded simulation (see optimistic-math.ts), not a published statistic — the point is the shape of the difference between the three strategies, not the exact numbers.
Part II
A Claim, Made in Advance
Optimistic UI is not a component you install. It is a claim the interface makes to its user — “this happened” — before anyone has actually checked.
Guillermo Rauch is the founder and CEO of Vercel (founded 2015, originally ZEIT, renamed 2020), the creator of Socket.IO, and credited as the original architect of Next.js(first released October 25, 2016). In 2014 he published “7 Principles of Rich Web Applications,” whose second principle — Act immediately on user input — argued that JavaScript “allows us to mask network latency altogether,” and that as a consequence “spinners or ‘loading indicators’ should become a rarity.” His worked example was Gmail: an archived email disappears from the inbox the instant you click, before the server has actually confirmed the archive, because the action is reversible and near-certain to succeed. His seventh principle, “Predict behavior,” pushes the same idea further — prefetching data ahead of the click, toward what he called “negative latency.” The through-line matters more than either principle alone: this was never a UI trick. It was a reordering of trust — the interface stops waiting for the server’s permission before telling the user what happened, and tells them immediately, then quietly checks its own work.
The loop itself has two halves. Apply the change to local state the instant the user acts, because their intent is knowable right away and, in the overwhelming majority of cases, matches what the server will eventually agree to. Reconcile after: if the server agrees, nothing visible needs to happen — the UI was already right. If it disagrees, roll back, visibly. React 19’s useOptimisticmakes this the framework’s own default: on failure, “the Transition still ends, and React renders with whatever value currently is” — rollback falls out of the state model, it is not imperative undo code you write by hand. Users tolerate an undone action far better than an unexplained one; a value that silently reverts, with no stated reason, reads as a system that cannot be trusted.
Optimistic UI is a bet. Every bet has a stake and an odds calculation.
Part 2.5, the honesty boundary
Local-first software, from the 2019 Ink & Switch essay by Martin Kleppmann and collaborators, takes that same bet and spends it on an entire architecture rather than one request: data lives on the device, fully readable and writable offline, and synchronizes when a network happens to be available — “sync is an optimization, not a precondition.” The essay names seven ideals for what that buys the user:
No spinners — your work at your fingertips, under 100ms regardless of network.
Not trapped on one device — your data survives a closed tab.
The network is optional — reads and writes both work offline, queued not blocked.
Seamless collaboration — concurrent edits merge, nobody sees a “locked” dialog.
The long now — your data outlives the vendor, in a format you can still read.
Security and privacy by default — a smaller central breach surface.
Ultimate ownership — deletion is real deletion, nothing phones home to function.
Kleppmann, M. et al., “Local-first software,” Ink & Switch (April 1, 2019) — the essay itself is not in dispute, but this dossier’s own verification pass could not fetch a readable byline directly from inkandswitch.com and instead relies on standard attribution plus confirmed venue and date; graded secondary in Sources below, not verified.
Ideal four is where a harder problem starts: what happens when two people bet on the same object at the same time? A Conflict-Free Replicated Data Type (CRDT), formally defined in 2011 by Marc Shapiro, Nuno Preguiça, Carlos Baquero and Marek Zawirski, is a data structure that can be edited independently on different machines and later merged automatically into one consistent result, with mathematical guarantees about that convergence — strong eventual consistency. Automerge and Yjs are the two general-purpose libraries a team is most likely to reach for. The common mistake is assuming a CRDT means conflicts don’t happen; what it actually guarantees is that they always resolve, deterministically — not that the resolution is what either person wanted.
Which returns to the bet. It is worth making when the stake is low (cheap to undo) and the odds are good (very likely to succeed); it becomes dishonest the moment either variable moves against you — an interface that shows “sent,” “paid,” or “confirmed” before that is actually, verifiably true is not being efficient. It is misrepresenting the state of the world to the person relying on it.
A widely-cited “Doherty threshold” (~400ms, Doherty & Thadhani, 1982) appears in this dossier’s own Part 6 but is deliberately not used as a headline number above: the dossier’s own verification pass “could not be verified against any working source” — no surviving article, dead links on two attempts. Graded unverified in Sources; Nielsen’s directly quoted three bands carry the argument instead.
Part III
Where Trust Moves First
Rauch’s “reordering of trust” is not a metaphor — it is a literal sequence, and the network only gets a vote partway through it.
Scrub through the five stages one optimistic mutation runs, and notice exactly where the honest visual language changes at each one.
One tap, five stages
On your device
In transit
The server's answer
Stage
IntentConfirm / rollback
Intent — You tap Send. The system already knows what you meant, before it has asked anyone.
Stage captions restate the dossier’s own Part 2.1 (“apply the user’s change to local state the instant they act”), Part 2.3 (“sync is an optimization, not a precondition”) and Part 7 (“reduced opacity…”, “the absence of a state change is the confirmation”) verbatim where quoted. The zone grouping — device / in transit / server — is this build’s own sequencing of that prose into a pipeline, not a diagram the dossier itself draws.
Part IV
Three Products, One Bet
Figma built its own multiplayer system rather than adopt a textbook CRDT, and co-founder Evan Wallace is explicit about why.
“Figma isn’t using true CRDTs though,” his engineering-blog post states. “Since Figma is centralized (our server is the central authority), we can simplify our system by removing this extra overhead.” Property changes “apply immediately on the client without server acknowledgment to maintain responsiveness,” with the client discarding its own optimistic state the moment the server’s authoritative version disagrees. The trade Figma accepted is exactly Part 2.3’s local-first ideal three, offline-first peer-to-peer editing, given up in exchange for ideals one and four (no spinners, seamless collaboration) done well inside a connected session. You do not need a textbook-pure CRDT to get most of the multiplayer feel — you need to pick the amount of decentralization your actual offline requirements demand.
Linear has publicly discussed building a “sync engine” as the backbone of its own speed, and a 2026 follow-up post describes using turbopuffer to keep catch-up latency predictable across tens of terabytes of sync actions. The lesson worth keeping, independent of the implementation: how fast an app feels after reconnecting from an hour offline is its own measured metric, distinct from how fast it feels while already online — a sync engine’s job is making the catch-up moment not read as a fresh cold start.
⇆
Linear’s sync-engine internals are graded unverified below — the dossier itself “could not fetch the full technical body… beyond its framing and title,” and treats the architecture as directionally confirmed only. A specific delivery-state case (iMessage) was named in this build’s own brief but is not in this dossier — it is left out here rather than asserted on an unsourced guess; Rauch’s own Gmail-archive case and Figma’s multiplayer stand in for it instead.
Part V
The Odds Are the Whole Question
Twelve identical bets, one dial. Every tap fills instantly — the optimism never wavers. What moves is only how often the server later disagrees, and how many of the twelve you personally watch get undone.
Rollback theatre
tap any circle — twelve optimistic likes
Tap a circle to place the bet.
Fired
0
Rollbacks witnessed
0
Actual rollback rate
—
measured, this run
Dialed failure rate
20%
below
ReliableFlaky
Each rollback above carries a stated reason rather than a silent snap-back, per Part 2.2’s own claim that “users tolerate an undone action far better than an unexplained one.” The resolve delay (480ms, fixed) and the random-but-seeded outcome sequence are this build’s own demonstration, not a number the dossier publishes — the point is watching the measured rollback rate converge on the dialed one as more bets are placed.
Challenge · Assign the Bet
Open
Four real actions. For each, choose Optimistic (render now, reconcile after) or Pessimistic (wait, then tell the truth) — using Part 8's own test: is it idempotent, reversible, low-stakes, and rarely wrong?
Send a chat message
Rename a file
Delete your account
Pay for an order
A payment and an account deletion fail at least one of the four questions hard. A rename and a chat message pass all four.
Insight
The fastest interface is the one that trusts itself, and knows exactly when not to.
Every optimistic bubble, every instantly-filled like, every task that appeared on the latency bench before the network had an opinion — none of it made the network faster. It made the interface stop waiting for the network’s permission before rendering what you had already, unmistakably, caused. That is a genuine gift, worth roughly one bit of trust per action. But it is only honest exactly as far as Part 8’s four questions say it is: idempotent, reversible, low-stakes, rarely wrong. The same architecture that makes Gmail’s archive button feel instant is, without that discipline, the same architecture that makes a “Payment successful” screen a lie told with total confidence. Speed was never the feature. Knowing which bets are safe to make silently was.
Mental model
Whenever an action is about to run and something on screen needs to look confirmed,
look for whether it is idempotent, reversible, low-stakes and rarely wrong — Part 8’s four questions, not a habit,
because a “sent” or “paid” rendered before it is actually true is not efficiency, it is the interface misrepresenting the world with confidence.
TomorrowFind one action in your own product that renders success before the server has answered. Run it through the four questions — if it fails even one, give it an honest wait instead of a faster lie.