How to sync state across multiple user devices?
multi-device presence and state coherence patterns.
attach userId to each socket, track active sockets per user, broadcast user state to all their sockets.
The multi-device problem
When a user opens your app on a phone and laptop, the server sees two separate WebSocket connections. If the user clicks a button on the phone, only the phone socket receives the response. The laptop socket is unaware, showing stale state. Without explicit synchronization, the devices diverge.
Socket-to-user mapping
Maintain a mapping of userId to all connected sockets. In the connection handler, extract userId from the JWT, then add the socket to a collection: usersWithSockets[userId] = usersWithSockets[userId] || []; usersWithSockets[userId].push(socket.id);. On disconnect, remove the socket from the list. This allows you to broadcast to all of a user's connections.
Central state store
For important state (user settings, document edits, presence status), store in a database or cache (Redis). When a user changes something on the phone, write to the store, then emit the updated state to all their sockets. This ensures both devices see the change. For example: user clicks settings on phone, server writes to database, server emits 'settingsUpdated' to all sockets of that user, laptop updates its UI.
Broadcast to all user sockets
Create a helper: io.to() sends to a single room. To send to all sockets of a user, join each socket to a user room on connect: socket.join('user:' + userId);. Then broadcast: io.to('user:' + userId).emit('stateChange', newState);. Both devices receive simultaneously.
Event deduplication
When a user's phone socket triggers an action, it will receive the broadcast notification too. To prevent the phone from processing its own request twice, either mark the original socket for exclusion or have the phone await the server's confirmation response before updating locally.
Clustered considerations
If you have multiple Node.js servers, each server knows only its local sockets. If the phone connects to server A and the laptop to server B, sending to the laptop via server A fails. Use a Redis adapter to broadcast room messages across all servers. Socket.IO's adapter system handles this transparently.
Interview question
A user's phone and laptop are both connected. The user changes their avatar on the phone. What's the best way to ensure the laptop also sees the new avatar?
- a.Have the phone make a REST API call to update the avatar, then hope the laptop polls for updates eventually.
- b.Broadcast the avatar change to all of the user's sockets via a room or user mapping.Correct
- c.Send a direct socket.emit() only to the phone's socket; the laptop will sync next time it reconnects.
- d.Update the database and wait for both devices to poll the server independently.
Why? this is the answer
Broadcasting to a user room ensures both connected devices receive the update instantly. REST polling introduces delay and inefficiency. Direct socket.emit() to only the phone means the laptop sees nothing until reconnect. Independent polling is asynchronous and defeats real-time synchronization.
Just read this? Test yourself on what you have been reading.
Read the original → socket.io
- #multi-device
- #presence
- #state-sync
- #user-mapping
- #real-time
Put your scrolling time to good use
Learn one idea, try a quiz and save useful cards for revision. Tezvyn makes it easy to learn and stay current in your tech field, a few minutes at a time.
The iPhone app is on the way
We are building it. Until it lands, nothing here is held back from you: every interview card, your saved cards, streaks and the job board all work in Safari, plus hundreds of free practice quizzes of thirty questions each. Sign in and it all carries over to the app the day it arrives.
Want it as an icon? Tap Share at the bottom of Safari, then Add to Home Screen. It opens full screen and the cards you have read stay available offline.
We are hiring for this. Every open role lists the topics its interview covers, so you can prepare for the real thing rather than guessing.
See open roles