Skip to content

DynamoDB Streams

Dynoxide supports DynamoDB Streams with all four view types: NEW_IMAGE, OLD_IMAGE, NEW_AND_OLD_IMAGES, and KEYS_ONLY.

Enabling streams

Streams are enabled per table through StreamSpecification on CreateTable or UpdateTable, exactly as on real DynamoDB:

aws dynamodb create-table \
  --endpoint-url http://localhost:8000 \
  --table-name Events \
  --key-schema AttributeName=pk,KeyType=HASH \
  --attribute-definitions AttributeName=pk,AttributeType=S \
  --stream-specification StreamEnabled=true,StreamViewType=NEW_AND_OLD_IMAGES

On an existing table:

aws dynamodb update-table \
  --endpoint-url http://localhost:8000 \
  --table-name Events \
  --stream-specification StreamEnabled=true,StreamViewType=NEW_AND_OLD_IMAGES

Over MCP, pass stream_specification to create_table or update_table.

One thing CreateTable rejects: setting StreamEnabled: false while also supplying a StreamViewType. A view type only means something when the stream is on, so the two can't be combined, and Dynoxide returns the same ValidationException DynamoDB does.

Reading records

The dynamodbstreams API works against the same endpoint:

# List streams
aws dynamodbstreams list-streams --endpoint-url http://localhost:8000

# Describe one to get its shard IDs
aws dynamodbstreams describe-stream \
  --endpoint-url http://localhost:8000 \
  --stream-arn <stream-arn>

# Get an iterator and read
aws dynamodbstreams get-shard-iterator \
  --endpoint-url http://localhost:8000 \
  --stream-arn <stream-arn> \
  --shard-id <shard-id> \
  --shard-iterator-type TRIM_HORIZON

Limits worth knowing

Streams expose a single shard. DescribeStream returns one shard, and its ExclusiveStartShardId and Limit paging parameters are accepted but ignored. If your code walks a multi-shard topology or tests shard splitting, that behaviour has no local equivalent here.

Bulk import does not generate stream records. dynoxide import bypasses stream recording for speed, so an import into a stream-enabled table produces no records. Recording starts for writes made after the import finishes. The import does carry the stream configuration across: if the --schema file's DescribeTable JSON contains a StreamSpecification, streams are enabled on the imported table with no extra flags.

Streams are not wired in the browser build. The WebAssembly preview reports its capability set at boot; streams are not in it. Gate on what the engine reports rather than assuming parity with the native build.

Over MCP

Four tools cover the stream API: list_streams, describe_stream, get_shard_iterator, and get_records. See the MCP docs.