Skip to content
Back to blog
Production note•Sep 24, 2026

Optimistic UI needs a recovery plan

Immediate feedback feels great until a write fails; design the rollback and truth source before animating success.

ReactUXReliabilityProduct

Speed is only half the experience

Clicking "bookmark" and seeing the icon fill immediately feels responsive. Clicking "send payment" and seeing a success screen before confirmation feels dangerous. Both are optimistic updates, but the consequences of being wrong are different.

Optimistic UI is a promise: "I expect this action to succeed, so I will show the likely result now." Every such promise needs a plan for when reality disagrees.

Pick actions with recoverable failure

Good candidates are low-cost, reversible actions with a high success rate: likes, bookmarks, simple preference changes. Even there, the server remains authoritative.

For actions with serious consequences, show a pending state until the server confirms the outcome. A payment, job application, account deletion, or inventory reservation should never be presented as complete on guesswork alone.

Design the whole state sequence

For a bookmark, write the timeline before the component:

idle -> optimistic saved -> server confirmed
                         -> server rejected -> previous value + explanation

What happens if the user taps twice while the first request is pending? What if another tab updates the same item? What if the request succeeds but the response is lost? These are product questions as much as state-management questions.

In React, useOptimistic provides a temporary view while an Action is in progress. It does not replace server validation, an error message, or a policy for conflicting writes. The committed value still needs to come from the confirmed operation or a fresh read.

Rollback without surprising the user

If the request fails, restore the previous value and explain why. A silent snap-back looks like a UI glitch. A toast that says "Could not save bookmark; try again" makes the state change legible.

For a list mutation, keep a stable item ID so the rollback affects the intended item even if sorting changes. For a counter, avoid blindly subtracting one after an error if several other updates may have arrived in the meantime; refresh the authoritative count or reconcile by operation ID.

Pending is a real state

Users need to distinguish "the interface responded" from "the system accepted it." A subtle pending marker can do that without making the UI feel slow. In a high-stakes flow, a clear progress state is better than a fake instant success.

The principle is simple: be fast where uncertainty is harmless, and be explicit where uncertainty matters. Optimism earns trust when the recovery path is as carefully designed as the happy path.

If you are building a web product and want it faster, cleaner, and easier to operate, I am open to collaborations.