Real-Time Change Data Capture

Real-time change data capture for accelerated datasets

Change data capture (CDC) in Spice reads inserts, updates, and deletes from a source transaction log or change stream and applies them to a local accelerated dataset. Applications query a copy that tracks the source in near real time, with no Kafka, Debezium, or full-table refreshes for PostgreSQL, MySQL, DynamoDB, and MongoDB.

Diagram of Spice.ai OSS capturing Debezium change data from source systems and dispatching changes to downstream services

Keep accelerated datasets current without full refreshes

CDC transfers only the rows that changed, so accelerated datasets stay synchronized with operational databases while queries run against the local copy.

100x

up to 100x faster queries

80%

up to 80% cost savings on data lakehouse spend

2x

increase in data reliability for critical workloads

Real-time dataset updates

Real-time dataset updates

Stream changes from source databases directly into Spice as they commit. Only modified rows are transferred, keeping datasets accelerated in Arrow, DuckDB, SQLite, Spice Cayenne, or PostgreSQL synchronized.

View the docs

Diagram of data sources and streams pushing create, update, and delete changes into Spice.ai acceleration
Optimized for acceleration

Optimized for acceleration

Combine CDC with a persistent acceleration engine, such as DuckDB or SQLite in file mode, Spice Cayenne, or PostgreSQL, for sub-second queries on live data. With a persistent engine, Spice resumes from the last known state after a restart instead of reloading the full table.

View the docs

Diagram of Spice.ai acceleration combining pull-based refresh from Kafka with push-on-change updates from PostgreSQL and Spice AI
Built for event-driven workloads

Built for event-driven workloads

Spice CDC keeps data current for event-driven workloads such as fraud detection, personalization, and IoT, where applications and AI agents act on the latest state of the source.

View the docs

Diagram of an event-driven flow where publishers move event data through an event data store to databases, files, and apps

Integrations across your data and observability stack

CDC is one refresh mode across 40+ prebuilt connectors for databases, warehouses, and object stores, from Databricks and S3 to MySQL and PostgreSQL. Datasets without CDC refresh on an interval or stay federated to the source.

How does change data capture work in Spice?

Spice change data capture reads row-level changes from a source's transaction log or change stream and applies them to a local accelerated dataset. With a native CDC connector (PostgreSQL, MySQL, DynamoDB, or MongoDB), each dataset runs in three stages:

  1. Snapshot: when no persisted state exists, Spice loads the table's existing rows into the acceleration engine. This happens on first start, and on every start of an in-memory acceleration.
  2. Stream: Spice reads new inserts, updates, and deletes from the source, such as the PostgreSQL write-ahead log, the MySQL binlog, DynamoDB Streams, or MongoDB change streams. Only changed rows cross the network.
  3. Apply: an apply loop buffers change events and coalesces them into batched writes to the accelerated dataset. With the default cdc_max_coalesce_age_ms of 0, it does not wait to fill a batch. A higher value trades a short delay for larger writes.

With Debezium sources, Debezium captures the changes instead. Push ingest posts events to Spice, which applies them. With Debezium over Kafka, Spice consumes the Kafka topic, then applies the events. A native CDC dataset sets refresh_mode: changes on a connector dataset in the Spicepod. A push-ingest dataset uses from: cdc:<name> with declared columns, and receives events on the runtime's CDC endpoint. Applications query the dataset through the same SQL endpoint as any other table, and Spice serves reads from the local copy:

datasets:
  - from: postgres:public.orders
    name: orders
    params:
      pg_host: db.example.com
      pg_db: production
      pg_user: ${secrets:PG_USER}
      pg_pass: ${secrets:PG_PASS}
      pg_sslmode: verify-full
    acceleration:
      enabled: true
      engine: duckdb
      mode: file
      refresh_mode: changes
      primary_key: order_id
      on_conflict:
        order_id: upsert

For the general pattern, including log-based, trigger-based, and polling CDC, see the change data capture guide.

Which databases does Spice CDC read from?

Spice captures changes natively from four databases and accepts Debezium change events for the rest:

SourceChange mechanismSource requirementKafka required
PostgreSQLLogical replication (pgoutput)wal_level=logicalNo
MySQLBinlog replication, as a replicalog_bin=ON, binlog_format=ROW, binlog_row_image=FULL, empty binlog_row_value_optionsNo
DynamoDBDynamoDB StreamsStreams enabled on the tableNo
MongoDBChange streamsReplica set or sharded clusterNo
Any Debezium source, such as SQL Server, Oracle, or Db2Debezium push ingest over HTTPDebezium source plugin, plus a cdc: dataset with declared columns, a primary key, and on_conflict upsertNo
Any Debezium sourceDebezium change events read from KafkaExisting Debezium and Kafka pipelineYes

Debezium push ingest sends JSON or Avro change events directly to the Spice runtime, so sources without a native Spice path also skip the message bus. Plain Kafka topics use refresh_mode: append instead. By default it adds new messages as rows. With a primary key and on_conflict upsert, a message replaces the row with the same key, but deletes are not applied.

How does CDC compare with interval refresh?

The refresh mode sets how an accelerated dataset follows its source. CDC is the only mode that applies updates and deletes without rereading the table:

Refresh modeWhat each refresh doesFreshnessBest fit
fullRereads and replaces the whole table on an intervalTrails by the refresh intervalSmall tables, or sources without a change log
appendAdds new rows or messages. A primary key with upsert can replace rows, but source deletes are not appliedCheck interval, or streaming for KafkaEvent, log, and Kafka tables that only grow
changesApplies inserts, updates, and deletes from the source log or change streamNear real timeOperational tables that change in place

A full refresh of a large table rescans the source on every interval and adds read load to the production database. CDC processes each change event as it arrives and sends only the changed rows. The DynamoDB Streams case study shows this pattern propagating configuration changes to thousands of nodes in under a second.

What does CDC require from the source?

CDC trades setup on the source for freshness. Plan for these requirements before enabling it:

  • Read access to changes: for PostgreSQL and MySQL, the Spice user needs replication privileges. For DynamoDB and MongoDB, it needs permission to read the table's stream or change stream. With Debezium push ingest, Debezium reads the source and posts events to Spice.
  • Row identity: updates and deletes are applied by primary key. Set acceleration.primary_key and an on_conflict upsert for that key on every engine except Arrow, including DuckDB, SQLite, PostgreSQL, and Spice Cayenne. For a PostgreSQL table without a primary key, also set a replica identity that sends those columns, such as REPLICA IDENTITY FULL.
  • Replication slots: by default, each PostgreSQL dataset on each Spice instance gets its own replication slot. Datasets that set the same pg_replication_slot share one slot, and each Spice instance still needs its own. Size max_replication_slots for the slots actually configured. An unused slot keeps WAL on the source until it is dropped.
  • Initial load time: the first snapshot makes startup slower than for a non-CDC dataset. After the snapshot, a PostgreSQL dataset reports Ready when replication lag falls below pg_replication_ready_lag (2 seconds by default). This is a readiness threshold, not a latency guarantee.
  • Encrypted transport: set pg_sslmode to require, verify-ca, or verify-full so the replication stream uses TLS.

CDC pairs with SQL federation and acceleration: tables that change often get CDC, and the rest stay federated or refresh on an interval in the same query. The same mechanism keeps the analytics replica and the operational data lakehouse current. To run CDC on a managed runtime, compare Spice Cloud plans and pricing.

Do more with your data

Run data-intensive workloads on a high-performance data runtime trusted by teams building real-time systems at scale.

Peter Janovsky

“Spice opened the door to take these critical control-plane datasets and move them next to our services in the runtime path.”

Peter Janovsky

Software Architect, Twilio

Darin Douglass

100x

Faster queries

“It just spins up and works, which is really nice. The responsiveness is amazing, which is a huge gain for the customer.”

Dustin Warner

“What I like the most about Spice is that it's very easy to collect data from different data sources, and I'm able to interact with this data and do everything in one place.”

Dustin Warner

Director of Software Engineering, NRC Health

FAQs

Answers to common questions about change data capture in Spice

Spice reads inserts, updates, and deletes from a database log, a change stream, or Debezium events. It applies each change to the accelerated dataset as the change arrives. Only modified rows are transferred, so the dataset stays current without full-table refreshes.

No, not for PostgreSQL, MySQL, DynamoDB, or MongoDB. Spice reads changes from these databases directly. For SQL Server, Oracle, or Db2, a Debezium plugin can send change events to Spice over HTTP without Kafka. Spice also reads Debezium events from an existing Kafka pipeline.

With a persistent acceleration engine, Spice resumes from the last known state. It does not reload the full table. For PostgreSQL, the replication slot is durable, and Spice continues from the slot position. With an in-memory engine, Spice reloads the dataset on restart.

CDC writes to Arrow, DuckDB, SQLite, Spice Cayenne, and PostgreSQL accelerations. Use DuckDB or SQLite in file mode, Cayenne, or PostgreSQL to keep the data across restarts. This pairs with data lake acceleration to serve fast queries over data that changes.

Set wal_level to logical and give the Spice user replication privileges. Then set refresh_mode: changes, primary_key, and an on_conflict upsert on the accelerated dataset. By default, Spice creates one replication slot per dataset, and datasets that name the same slot share it. For a table without a primary key, also set REPLICA IDENTITY FULL so Spice can apply updates and deletes.

Spice buffers change events and writes them to the accelerated dataset in batches. By default, it does not wait to fill a batch, so changes reach the local copy in near real time. The exact delay depends on source write volume and runtime load. Spice does not guarantee a fixed latency.

Event-driven workloads such as fraud detection, personalization, and IoT benefit most. These workloads act on the latest state of the source. CDC also keeps data current for retrieval-augmented generation, so responses use live data.

See Spice in action

Walk through your use case with an engineer and see how Spice handles federation, acceleration, and AI integration for production workloads.

Talk to an engineer (opens in a new tab)