Whether you need to save remote objects on the server or not completely depends on your needs. You will need a remote flag locally to mark it as remote for synchronization, possibly also on the server, depending on your desire to rollback.
I already took a little care of this problem. Here is one of the possibilities:
When a client deletes something, simply mark it so that it is deleted locally and deleted from the server during synchronization (at this point you can clear the kernel data). When other clients request access to this data, send HTTP 404 because you no longer have the object. At this point, the client can delete the object locally. Now, if the client requests a list of things and this object has been deleted, it will simply be absent from the list of things that it receives so that you can detect it and delete it. I do this in the client, creating an array of object identifiers when I get a response from the server and delete any local objects that do not have these identifiers.
We have a remote field on the server, but just to be able to roll back in case something is accidentally deleted.
Of course, you can return the deleted objects to the client so that they know what to delete, but if you do not want to store a copy on the server, you will need to assume that all clients will be updated for a period of time, then you can collect garbage after this expires time interval.
I really don't like this solution. If your data is too heavy to request all objects for complete synchronization, you can use your current merge strategy to create and update, and then run a separate call to check for deleted items. This call can simply request all the identifiers that the client must have on the device. It can remove those that do not exist. OR he can send all identifiers on the client and return a list of identifiers for deletion.
I think you need to provide more detailed information about the nature of the data if you want a more stubborn offer.
source share