In most cases, I would probably do it like this:
- Store an initial state plus all changes made since that state (all timestamped).
- Poll only for changes since the last timestamp retrieved.
- If someone posts an update, send the last-seen timestamp with it. If there have been updates since then, deal with that accordingly. (See below)
- Periodically, calculate the state of the data at a given time.
- When you load the state fresh, only load the last-calculated state plus changes made since that.
When I say "deal with that accordingly," I mean that it very much depends on the case. If I can safely make the second update and send the missing update back to the client, I will do. But sometimes you will want to inform the user of a double update and allow them to make the decision what to do next.