Cdc

Change feed (CDC)

/ Changes, / Cdc, / Replication

Change feed (CDC) #

GET /_changes serves a collection’s change log tail from the shard engines’ WALs, so external systems can replicate Pizza data elsewhere — off-site disaster recovery, secondary indexing, audit pipelines — with a standard poll loop:

GET /demo:orders/_changes?since=abc:3,def:1&limit=1000
{
  "results": [
    {"shard":"abc…","rolling_id":0,"epoch_id":4,"seq":0,
     "id":"0,7","key":"u1","op":"create","doc":{"qty":3}},
    {"shard":"abc…","rolling_id":0,"epoch_id":4,"seq":1,
     "id":"0,8","op":"delete"}
  ],
  "cursors":     {"abc…": 4, "def…": 1},
  "purged_below": {"abc…": 3},
  "active":      {"abc…": 5},
  "pending":     true
}

Request #

GET /_changes
GET /<targets>/_changes

Path parameters #

  • targets
    (Optional, string) Comma-separated collection names (wildcard supported); the target-less form feeds every collection.

Query parameters #

  • since
    (Optional, string) Per-shard epoch cursors from a previous response, shard_hex:epoch,shard_hex:epoch. Omit to start from the beginning of the retained tail.
  • limit
    (Optional, integer) Maximum rows to return. Defaults to 1000.

Consuming the feed #

  1. Poll with the cursors of the previous response as the next since (persist the cursors — they are the checkpoint).
  2. pending: true means more rows exist beyond limit; poll again immediately, otherwise poll at your cadence.
  3. Compare each cursor against purged_below: a cursor below that floor means the WAL retention window (wal.local.retention_epoch / retention_bytes) has already purged part of the tail for that shard. The tail is incomplete — run a full resync (search + re-bulk into the DR cluster) and resume from the current cursors.

graph TD P("poll — since = the cursors you saved") --> R["rows + new cursors"] R -->|"pending: true — rows remain past limit"| P R --> C{"every cursor at or above
purged_below?"} C -->|"yes — the tail is complete"| W["persist the cursors,
poll again at your cadence"] C -->|"no — retention already purged
part of the tail"| X["full resync: search + re-bulk,
resume from the current cursors"]

...