One problem that I encountered sending delta updates (basically the 4th option) is that the data may be inoperative or just old, depending on how synchronous your server is, basically the conditions of several races clients updating the server at the same time.
My solution was to send an update notification to all clients with a bitmask setting a bit for each updated item.
The client then requests the current value of the specific data based on the bitmask. It also allows the client to request only the data of interest.
The advantage of this is that he avoids the conditions of the race, and the client always receives the latest value.
The disadvantage is that two-way traffic is required to get the actual value.
UPDATE to demonstrate what I'm trying to do.
Suppose 4 clients A, B, C, D. A and B send simultaneous updates to the mutable state X on server Xa and Xb. As B gets a bit later than A, the final state of X on the server is X = Xb.
The server sends an updated status when it receives it for all clients, so C and D receive an updated status of X, because the delivery order is uncertain. C receives Xa, then Xb and D receives Xb, then Xa, so in this case, clients C and D have different ideas about the state of X, one reflects that the other server does not, it has outdated (or old) data.
On the other hand, if the server just sends a notification that X has changed to all clients, C and D will receive two status notifications for X. They both make requests for the current state of X, and both of them end up with the final state of X on a server that is Xb.
Since the order of the status notification does not matter, since there is no data in it, and the clients issue a request for an updated status for each notification, they both end with consistent data.
Hope it is more clear what I was trying to do.
Yes, this increases the delay, but the developer must decide, more importantly, the delay or the presence of all clients reflecting the same state of the data being changed. It will depend on the data and the game.