In gNMI Subscribe, how do the ONCE, POLL and STREAM subscription-list modes differ, and what does sync_response tell the collector in each?
answer
- how long the RPC lives
- who triggers each round of updates
- an empty Poll message
- everything sent at least once
- the default mode
basics
~20 sIn gNMI, ONCE sends all subscribed values, a sync_response and closes the RPC; POLL keeps the RPC open and answers each Poll message with values plus a sync_response; STREAM sends initial values, one sync_response, then updates indefinitely.
solid answer
~40 sThe `mode` of a gNMI `SubscriptionList` sets how long the subscription lives; the default is `STREAM`. `ONCE` is a one-off: the target sends updates for every subscribed path, then a `SubscribeResponse` with `sync_response` set to true, then closes the RPC. `POLL` keeps the RPC open; each time the collector sends a `SubscribeRequest` carrying an empty `Poll` message, the target sends all the paths again and ends that round with `sync_response`. `STREAM` sends every path once, marks the end of that initial pass with a single `sync_response`, and then keeps sending updates by each path's `SAMPLE` or `ON_CHANGE` trigger. In every mode `sync_response` means the same thing: every value covered by the subscription has been sent at least once, so the collector's view is complete. It does not mean a consistent point-in-time snapshot.
go deeper
Recall the three list modes by lifetime: ONCE closes after one pass, POLL waits for the client to ask again, STREAM keeps sending until cancelled.
Explain the message flow in each mode, the empty Poll message, and that sync_response means every subscribed value was sent at least once, not a consistent snapshot.
Show the operational consequences: build the collector's cache around sync_response, never assume timestamp order, and open new RPCs rather than trying to modify a live subscription.
Decide which data classes deserve a permanent STREAM, which are better pulled with POLL or ONCE, and what that means for connection counts across the estate.
## Where the modes sit **gNMI** is an OpenConfig specification (version 0.10.0), not an IETF RFC. Its `Subscribe` RPC starts with a `SubscribeRequest` whose `subscribe` field holds a **`SubscriptionList`**: the paths, an optional common `prefix`, and a **`mode`** describing the subscription's longevity. There are three list modes, and they are distinct from the per-path modes (`SAMPLE`, `ON_CHANGE`, `TARGET_DEFINED`) that only apply inside `STREAM`. If the client leaves `mode` unset, the default is **`STREAM`**. ## The three modes | Mode | RPC lifetime | What triggers updates | sync_response | |---|---|---|---| | `ONCE` | closed by the target after one pass | the request itself | once, then the RPC closes | | `POLL` | long-lived | each `Poll` message from the client | after every poll round | | `STREAM` | long-lived, until cancelled | per-path `SAMPLE` / `ON_CHANGE` / `TARGET_DEFINED` | once, after the initial pass | 1. **ONCE.** The target generates updates for all data under the subscribed paths, sends a `SubscribeResponse` with `sync_response` true, and **must close the RPC**. It behaves like a request-response exchange carried over the subscription machinery. 2. **POLL.** The subscription is created once, then the collector drives it: it sends a `SubscribeRequest` whose `poll` field is an **empty `Poll` message** on the **same RPC**. The target generates updates for every subscribed path and, after each round, sends `sync_response` true. 3. **STREAM.** The target sends updates for all matching paths, then `sync_response` true to say the initial pass is done; later updates follow each path's trigger. No further `sync_response` is required. ## What sync_response does and does not mean The specification defines `sync_response` as a signal that **all data values for the subscribed paths have been transmitted at least once**. For a collector that keeps a cache, it is the point at which the cache is complete and, for example, a dashboard can stop showing "loading". It is **not** a snapshot marker: - Subscription updates are **independent** messages; the specification says a client cannot assume they represent the data tree at one moment. - Notifications are **not required to arrive in timestamp order**, and clients must not assume they do. That independence is deliberate. The specification notes that a `ONCE` or `POLL` view can be **more resource-efficient than a `GetRequest`** for a large subtree, because the target does not have to assemble a coalesced snapshot in memory before sending. ## updates_only and paths that do not exist yet - With `updates_only` set to true, the target skips the initial values: a `STREAM` subscription sends `sync_response` first and then only changes; for `POLL` and `ONCE` only the `sync_response` is sent. - A subscribed path that is valid in the schema but does not exist yet is not an error. `ONCE` and `POLL` return no value for it; `STREAM` sends nothing for it and keeps the RPC open, reporting it if it appears later. ## Subscriptions are fixed for their lifetime A gNMI subscription's paths **cannot be modified**. To watch more paths the collector opens **another `Subscribe` RPC** with a new `SubscriptionList`. Sending a second `SubscriptionList` on an RPC that already has one is answered with an error carrying `InvalidArgument`, and other `Subscribe` RPCs on the session are left alone. To end a subscription, the client **cancels the RPC** or closes the session. ## Choosing on the 2,000-device estate - **STREAM** for the continuous feed: counters sampled, status on change. - **POLL** where a collector wants values on its own schedule over a connection it keeps open, without re-sending the subscription each time. - **ONCE** for inventory-style reads: part numbers, software versions, a one-off audit of a subtree.
- Why would a collector use a gNMI ONCE subscription instead of a Get for a large subtree?A `GetRequest` returns a snapshot the target must assemble before sending. The specification notes a `ONCE` or `POLL` view can be more resource-efficient for large subtrees because the target sends per-element updates as it reads them, with no coalesced in-memory view. The trade-off is that the updates are independent, not one consistent snapshot.
- Can a collector add a path to a running gNMI STREAM subscription?No. Subscriptions are set once. A second `SubscriptionList` on the same RPC is answered with an `InvalidArgument` error, while other Subscribe RPCs on the session continue. The collector opens a new `Subscribe` RPC for the extra paths, or cancels and recreates the original one.
saying these in an interview costs you the question
- A gNMI POLL subscription opens a new RPC for every poll.
- In STREAM mode, sync_response follows every batch of updates.
- A ONCE subscription returns an atomic point-in-time snapshot of the subtree.
- Extra paths can be added by sending another SubscriptionList on the same RPC.
- The default SubscriptionList mode is ONCE, so STREAM must be set explicitly.