Script Valley
WebSockets & Real-Time Applications
Real-Time Patterns and ArchitectureLesson 5.1

Optimistic UI updates with WebSockets

optimistic update pattern, client-side state mutation, server confirmation, rollback on failure, message ID tracking, UI state reconciliation, latency hiding

Show the Update Before the Server Confirms It

Waiting for a server round trip before updating the UI adds 50โ€“300ms of visible lag. Optimistic updates apply the change locally first, then confirm or roll back based on the server response:

// Assign a client-generated ID to each message function sendMessage(text) { const tempId = crypto.randomUUID(); // 1. Show immediately addMessageToUI({ id: tempId, text, status: 'sending' }); // 2. Send to server socket.emit('chat:send', { tempId, text }, (response) => { if (response.ok) { // Replace temp with server-confirmed message updateMessage(tempId, { id: response.id, status: 'sent' }); } else { // Roll back removeMessage(tempId); showError('Failed to send message'); } }); }

What Can Go Wrong

Optimistic updates break when: the server rejects the action due to validation (show an error, roll back); the network drops and the ack never arrives (use timeout on ack, roll back after N seconds); or two clients edit the same resource simultaneously (the server must detect conflict and tell clients to reconcile). For simple chat, optimistic updates are safe. For collaborative editing, you need operational transforms or CRDTs to resolve conflicts.

Up next

How to handle missed messages during WebSocket reconnection

Sign in to track progress

Optimistic UI updates with WebSockets โ€” Real-Time Patterns and Architecture โ€” WebSockets & Real-Time Applications โ€” Script Valley โ€” Script Valley