I'll attempt to answer your questions from the client's perspective:
What is this feature trying to solve?
Its intended to reduce the load on kube-apiserver from clients that issue Watch requests for a resource type. Bookmarks are intended to let the client know that the server has sent the client all events up to the resourceVersion specified in the Bookmark event. This is to make sure that if the watch on the client side fails or the channel closes (after timeout), the client can resume the watch from resourceVersion last returned in the Bookmark event. It's more like a checkpoint event in the absence of real mutating events like Added, Modified, Deleted.
The client could already be caching the resourceVersion that is received as part of the regular Added, Modified, Deleted events, but consider a case where the resource you're watching has had no updates in the last 30 minutes and the resourceVersion you have cached is "100".
In the absence of bookmark events, you will attempt to resume from "100", but the server could return a "410 Gone" indicating that it doesn't have that version or it is too old. In that case, the client will have to do a List to get the latest resourceVersion and initiate a watch from there or start the watch from latest by specifying no resourceVersion, which is more expensive for the server to process.
In the presence of bookmark events, the server might attempt to send you a Bookmark event with resourceVersion "150" indicating that you have processed up that version and in the event of a restart you can start processing from there onwards.
This contrived example in the documentation shows just that. You start your watcher at rv="10245", you process some events up to rv="10596" and then the server sends you a bookmark with rv="12746" so in the event of a restart you can start processing from there onwards.
GET /api/v1/namespaces/test/pods?watch=1&resourceVersion=10245&allowWatchBookmarks=true
---
200 OK
Transfer-Encoding: chunked
Content-Type: application/json
{
"type": "ADDED",
"object": {"kind": "Pod", "apiVersion": "v1", "metadata": {"resourceVersion": "10596", ...}, ...}
}
...
{
"type": "BOOKMARK",
"object": {"kind": "Pod", "apiVersion": "v1", "metadata": {"resourceVersion": "12746"} }
}
When should I use it?
For efficient processing of change events on the resource your watching, it seems better to process Bookmarks than to not. There are no guarantees round the delivery of Bookmarks though - the server might not support it (if it is running an older version of Kubernetes), or it might not send them at all.
Can I not use and not miss events?
Yes, you could totally do that, but your likelihood of missing events decreases if you use Bookmarks. Also remember that it not only benefits the client but also the kube-apiserver, because it could return events from its local cache if it has the "fresh" resourceVerion you received in a Bookmark, in the absence of which it will have to do a consistent-read from etcd. I recommend this video to understand how Watch events work under the hood.
How do I use it?
Depending on which client library you're suing the usage might be different, but in a raw HTTP request you can specify this query param: allowWatchBookmarks=true
GET /api/v1/namespaces/test/pods?watch=1&resourceVersion=10245&allowWatchBookmarks=true
If you're using client-go, there is a tool called Reflector, and this is how it requests bookmarks and this is how it processes it.
What should I do when I receive a Bookmark event?
Extract the resourceVersion from the Bookmark event and cache it for when you try to restart your watcher for any reason.