Skip to main content

What is an "optimistic update"?

What an "optimistic update" is

An optimistic update is an approach where the UI updates immediately, before the server has confirmed the data change.

That is, the application optimistically assumes the server operation will succeed, and updates the interface instantly, so the user does not feel a delay.


Example without an optimistic update:

javascript
async function handleLike(postId) { await fetch(`/api/posts/${postId}/like`, { method: "POST" }); refetch(); // wait for the server's response, then update the UI }

Downsides:

  • The "like" button is clicked → but the UI does not change until the response arrives.
  • The user feels a 300-500 ms delay (or more on a bad connection).
  • The app feels "sluggish".

Example with an optimistic update:

javascript
const queryClient = useQueryClient(); async function handleLike(postId) { // 1. Update the UI locally right away queryClient.setQueryData(['post', postId], (old) => ({ ...old, likes: old.likes + 1, isLiked: true, })); try { // 2. Send the request to the server await fetch(`/api/posts/${postId}/like`, { method: 'POST' }); } catch (err) { // 3. If the server responds with an error, roll back the changes queryClient.invalidateQueries(['post', postId]); } }

The user sees the update instantly, even without a response from the server. Once the server confirms, everything is already in sync. If the server responds with an error, the data rolls back to the actual state.


A visual scenario

EventWhat the user seesWhat happens in the code
Clicked the "like" buttonthe like becomes activesetQueryData() updates the cache immediately
The server receives the requestnothing changes in the UIfetch() runs in the background
The server responds 200 OKeverything stays as isthe cache remains current
The server responds 500the like disappearsa rollback (invalidateQueries or rollback)

Why this matters

1. Instant response

The user feels the app works "in real time", with no delay even on a slow network.

2. Smooth UX

The interface reacts right away, without loader "flickers". Optimistic updates are especially important in interactive actions:

  • likes,
  • commenting,
  • voting,
  • changing a name, status, or an item's position in a list.

3. Independence from the network

If the request fails, the local changes can be rolled back. The user does not lose context (they see that the action "got cancelled").


How it is implemented in practice

1. React Query

javascript
import { useMutation, useQueryClient } from '@tanstack/react-query'; function useLikePost() { const queryClient = useQueryClient(); return useMutation({ mutationFn: (postId) => fetch(`/api/posts/${postId}/like`, { method: 'POST' }), // 1. Optimistically update the cache onMutate: async (postId) => { await queryClient.cancelQueries(['post', postId]); const prevPost = queryClient.getQueryData(['post', postId]); queryClient.setQueryData(['post', postId], (old) => ({ ...old, likes: old.likes + 1, isLiked: true, })); // 2. Return data for a rollback return { prevPost }; }, // 3. On error, roll back onError: (err, postId, context) => { queryClient.setQueryData(['post', postId], context.prevPost); }, // 4. On success, update or invalidate onSettled: (postId) => { queryClient.invalidateQueries(['post', postId]); }, }); }

onMutate → local update onError → rollback onSettled → final update/validation


2. SWR (Vercel)

javascript
import useSWR, { mutate } from 'swr'; function likePost(postId) { // optimistically increase the like count mutate(`/api/posts/${postId}`, async (data) => { await fetch(`/api/posts/${postId}/like`, { method: 'POST' }); return { ...data, likes: data.likes + 1, isLiked: true }; }, { optimisticData: { ...data, likes: data.likes + 1, isLiked: true }, rollbackOnError: true }); }

3. Redux Toolkit Query

RTK Query also lets you temporarily update the cache locally:

javascript
const [updatePost] = useUpdatePostMutation(); updatePost(newData) .unwrap() .then(() => dispatch(api.util.invalidateTags(['Post']))) .catch(() => revertLocalState());

4. Typical use cases for optimistic updates

ActionWhat we update locally
LikeIncrease the like counter
Adding a commentAdd the comment to the list
Deleting an itemRemove it from the UI before the server responds
Editing a profileChange the name/avatar locally
ReorderingRearrange the items locally
Payment / orderMark it "created" before server confirmation

Summary

What Optimistic Update doesWhy it matters
Updates the UI before the server respondsinstant response
Improves UX and perceived speedno "delay" during interaction
Syncs up on successthe UI and server stay consistent
Rolls back on errorreliable on an unstable network
Cuts down the number of loading statesthe interface feels "alive"

In short:

An optimistic update is a way to make the interface instantly responsive: the UI updates right away, optimistically assuming success, and if the server returns an error, React rolls back the changes.

Short Answer

Interview ready
Premium

A concise answer to help you respond confidently on this topic during an interview.