How does a YANG-Push on-change subscription keep a collector's copy of interface state in sync, and how does the receiver notice a lost update?
answer
- a full picture first, then deltas
- YANG Patch edits
- one dampening period per subscription
- a counter in patch-id
- a flag for missing data
basics
~20 sA YANG-Push on-change subscription starts with a full push-update when sync-on-start is true, then sends push-change-update YANG Patch deltas. A receiver detects loss through gaps in a counting patch-id or an incomplete-update flag, then resynchronises.
solid answer
~50 sYANG-Push (RFC 8641) builds on RFC 8639. With `sync-on-start` true, the default, an on-change subscription first sends a **`push-update`**: the whole filtered subtree, like a retrieval. After that it sends **`push-change-update`** notifications whose content is a YANG Patch (RFC 8072) of `create`, `delete`, `replace`, `insert` and `move` edits from the last reported state. A `dampening-period`, in centiseconds and default 0, limits how often update records are built for the whole subscription; only the value current at the end is sent. For loss, the publisher **should** use `patch-id` as a counter from 0 that increments with every `push-change-update` and resets to 0 at each resync, so a gap shows a missing record. If it knows a record is missing data it sets **`incomplete-update`**. The receiver then resyncs, for a dynamic subscription with the `resync-subscription` RPC, which brings a fresh `push-update`.
code
xml · 21 lines<notification xmlns="urn:ietf:params:xml:ns:netconf:notification:1.0">
<eventTime>2026-10-01T08:22:33.44Z</eventTime>
<push-change-update xmlns="urn:ietf:params:xml:ns:yang:ietf-yang-push">
<id>1011</id>
<datastore-changes>
<yang-patch>
<patch-id>42</patch-id>
<edit>
<edit-id>edit1</edit-id>
<operation>replace</operation>
<target>/ietf-interfaces:interfaces</target>
<value>
<interfaces xmlns="urn:ietf:params:xml:ns:yang:ietf-interfaces">
<interface><name>eth0</name><oper-status>down</oper-status></interface>
</interfaces>
</value>
</edit>
</yang-patch>
</datastore-changes>
</push-change-update>
</notification>go deeper
Recall the two notification types: push-update carries the full subscribed data, push-change-update carries only what changed since the last record.
Explain sync-on-start, YANG Patch operations, and how a dampening period sets one minimum interval for the whole subscription and reports only end-of-period values.
Show how you would run it: detect gaps from the patch-id counter, act on incomplete-update, resync with resync-subscription, and keep counters on periodic subscriptions.
Decide how much correctness the collector needs: periodic full resyncs versus trusting deltas, dampening against alert latency, and what a gap should trigger downstream.
## The setting A collector keeps a live copy of interface state for 2,000 devices, fed by **YANG-Push**, the IETF's datastore subscription mechanism (**RFC 8641**, Standards Track), built on the subscription framework of **RFC 8639** and carried for dynamic subscriptions over NETCONF (RFC 8640) or RESTCONF (RFC 8650). Interface `oper-status` changes rarely, so the subscription is **on-change** rather than **periodic**. The interview question is how the copy becomes correct and how anyone knows when it stops being correct. ## Step 1: a full picture An on-change subscription has a **`sync-on-start`** parameter, a boolean with default **true**. When true, the publisher sends a **`push-update`** when the subscription starts: a complete, filtered copy of the subscribed subtree, equivalent to what a retrieval with the same filter would return. This sets the frame of reference. With `sync-on-start` false, no `push-update` is ever sent and only changes arrive, which suits a receiver that already holds the state. ## Step 2: deltas as YANG Patch After that, changes arrive as **`push-change-update`** notifications. Their content is a **YANG Patch** (RFC 8072), so each edit says what kind of change happened: | Operation | Used when | |---|---| | `create` | a node was created | | `delete` | a node was deleted | | `replace` | only the value changed | | `insert` | a new entry was inserted in a list | | `move` | an entry in a user-ordered list moved | Two parameters shape the stream: - **`dampening-period`** (centiseconds, default 0) is the minimum interval between building successive update records for the subscription. It applies to **the whole subscription**, not to each node. Changes during the period are collected, and the record carries each node's value at the end of it. - **`excluded-change`** drops change types, for example reporting only creation and deletion and never `replace`. Dampening has one subtle rule: if a node changes and changes back within the period, the publisher still reports it, with its current value, to show that churn happened. A link that flaps down and up while a dampening period is already running produces one edit at the end of that period that looks like no change at all, and that edit is the evidence of the flap. ## Step 3: noticing loss YANG-Push does not retransmit lost records; it makes loss visible. 1. **`patch-id` as a counter.** RFC 8072 allows any string, but RFC 8641 says the publisher **should** put a counter there: start at 0, add one per `push-change-update`, reset to 0 on every resync (a new `push-update`), and reset to 0 after 4294967295, the `uint32` maximum. A receiver that sees 41 then 43 knows a record went missing. 2. **No reordering.** Update records for one subscription must not be resequenced before transport, so a gap is not just late delivery. 3. **`incomplete-update`.** When the publisher knows a record is missing information, it must set this flag. If it cannot produce a record at all, it must suspend the subscription. 4. **Transport loss.** Per RFC 8639, losing the transport terminates a dynamic subscription and suspends a configured one; it never fails silently. Recovery is the receiver's choice: wait, re-read the data, or resync. For a dynamic on-change subscription the **`resync-subscription`** RPC asks the publisher to send a new `push-update`, which also resets the `patch-id` counter. ## Step 4: what on-change never covers On-change is not available for every node. RFC 8641 gives `in-octets` (RFC 8343) as an example of a node a publisher may not support on-change for, because it changes all the time. A publisher may accept an on-change subscription whose filter includes such nodes and **silently leave them out**, or reject it with the `on-change-unsupported` error. RFC 9196 defines capability data, such as `on-change-supported`, through which a publisher can say what it supports. Counters belong on a **periodic** subscription with a `period` and optional `anchor-time`. ## The record on the wire The example below follows RFC 8641's on-change figure: subscription `id` 1011, the counter at 42, and one `replace` edit reporting the interface going down.
- Why can a YANG-Push on-change update report a value identical to the one the receiver already has?Within a dampening period a node may change and change back. RFC 8641 says the current value is still sent so the receiver knows churn occurred; the YANG Patch edit then applies as no net change. A `create` for a node the receiver already holds is valid in YANG-Push, even though plain YANG Patch would treat it as an error.
- An on-change YANG-Push subscription to a whole interface subtree never reports in-octets. Is that a bug?Not necessarily. A publisher may accept an on-change subscription and silently exclude nodes it cannot report on change; RFC 8641 names `in-octets` as an example. The subscriber should check the publisher's on-change capability, for example RFC 9196's `on-change-supported`, and put counters on a periodic subscription.
saying these in an interview costs you the question
- A dampening period queues every intermediate change and replays them in order.
- patch-id carries the time at which the change happened.
- YANG-Push automatically retransmits a lost push-change-update.
- An on-change subscription reports every node in its filter, byte counters included.
- With sync-on-start false, the first notification is still a full push-update.