Skip to content

Change streams (CDC)

fdyno implements DynamoDB Streams using FoundationDB versionstamps. A change record is written as part of the same transaction as the mutation that produced it, rather than by a separate capture process.

How records are written

When a table has a stream enabled, every item mutation writes a change record into the table's v/ subspace in the same transaction as the mutation itself:

flowchart LR
    W["PutItem / UpdateItem / DeleteItem"]
    subgraph txn["single FoundationDB transaction"]
      I["i/ · base item"]
      X["x/ · indexes"]
      V["v/<versionstamp> · change record"]
    end
    W --> txn

The record key uses SetVersionstampedKey, so FoundationDB stamps it with a globally-ordered 10-byte versionstamp assigned at commit time. That gives every change a total, monotonic sequence number without a coordinator. Because the record is part of the ACID write, a change can never be lost or duplicated relative to the data mutation that produced it.

Stream view types

All four DynamoDB StreamViewType values are supported:

View type Record contains
KEYS_ONLY Only the key attributes of the changed item
NEW_IMAGE The item as it appears after the change
OLD_IMAGE The item as it appeared before the change
NEW_AND_OLD_IMAGES Both images

The Streams API

fdyno serves the DynamoDB Streams control and read APIs:

  • ListStreams
  • DescribeStream
  • GetShardIterator
  • GetRecords

A consumer reads exactly as it would against DynamoDB Streams: list streams, describe to find shards, get an iterator, then page through records.

Difference from DynamoDB

DynamoDB partitions a stream across many shards that mirror the table's internal partitions. fdyno uses a single logical shard per table, ordered by the versionstamp, giving a single global order. It provides the ordered change-feed semantics consumers depend on but does not reproduce DynamoDB's shard-splitting topology. See Compatibility for the full list of differences from DynamoDB.