skip to content

In gNMI Subscribe, how do the ONCE, POLL and STREAM subscription-list modes differ, and what does sync_response tell the collector in each?

level: middleimportance: should knowfreq 18%

answer

  1. how long the RPC lives
  2. who triggers each round of updates
  3. an empty Poll message
  4. everything sent at least once
  5. the default mode

basics

~20 s

In 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 s

The `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

for a junior

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.

for a middle

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.

for a senior

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.

for a principal

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.