Skip to main content

Change Data Capture Explained: Real-Time Database Sync Without the Polling Tax

· 5 min read
blog-writer

Every production database is a stream of state changes masquerading as a static store. A row gets inserted, updated, deleted — and that event disappears into the void unless something is watching.

Change Data Capture (CDC) is the discipline of watching that stream at the source and routing every change to wherever it needs to go — data warehouses, caches, search indexes, AI agents — in real time, without touching your application code and without the overhead of polling.

This post explains how CDC works mechanically, why polling is architecturally broken for event-driven systems, and how OpenCLAW's CDC pipelines give your AI agents a live view of your database state.


The Polling Problem​

The naive solution to database sync is polling: query the database every N seconds, compare results to the last snapshot, infer what changed.

-- Classic polling pattern
SELECT * FROM orders
WHERE updated_at > '2025-05-25 18:00:00'
ORDER BY updated_at;

This works at small scale. At production scale, it breaks in predictable ways:

ProblemImpact
LatencyN-second delay minimum — worse at load
Database loadFull table scans on every poll cycle
Missed deletesupdated_at doesn't change on DELETE
Race conditionsHigh-frequency updates between polls create gaps
Thundering herdAll pollers hit the DB at the same interval

More fundamentally: polling inverts the correct data flow. Your consumers should react to what changed, not query for it. Polling forces every consumer to be responsible for its own staleness — CDC pushes that responsibility to the source, once, correctly.


How CDC Works: Reading the Transaction Log​

Modern databases maintain a transaction log (also called the write-ahead log, or WAL) for durability. Every INSERT, UPDATE, and DELETE is written to this log before it's committed to disk. The log exists for crash recovery — CDC piggybacks on it for streaming.

Application → INSERT into orders
↓
Postgres WAL receives entry:
{ lsn: "0/1A3B4C", op: "INSERT", table: "orders",
row: { id: 9001, customer_id: 42, total: 149.99 } }
↓
CDC connector reads WAL (logical replication slot)
↓
Event published to downstream consumers

This approach has three properties polling can't replicate:

  1. Zero application changes — CDC reads the log directly, no code changes needed
  2. Complete change fidelity — every operation is captured, including deletes
  3. Sub-second latency — WAL entries are available as soon as the transaction commits

CDC Event Anatomy​

A CDC event carries structured metadata your consumers can act on directly:

{
"op": "update",
"ts_ms": 1748197200000,
"source": {
"connector": "openclaw-postgres",
"table": "orders"
},
"before": { "id": 9001, "status": "pending" },
"after": { "id": 9001, "status": "paid" }
}

The before/after diff means consumers don't need to re-fetch the row to understand the transition — essential for audit logs, cache invalidation, and AI agent triggers.


OpenCLAW Pipeline Architecture​

OpenCLAW structures CDC as a pipeline route — a configured path from a source connector to one or more sinks.

Source (Postgres / MySQL / MongoDB)
↓
OpenCLAW CDC Connector (reads WAL)
↓
Routing layer (filter, transform, fan-out)
↓
Sinks:
├── Kafka ├── Snowflake / BigQuery
├── S3 ├── Postgres (replica)
├── Webhook └── ADL (AI agent triggers)

Fan-out is first-class: one source feeds multiple sinks simultaneously. Your warehouse, search index, and AI agents all receive the event from one pipeline route.

Reliability Features​

  • At-least-once delivery with offset tracking
  • Dead letter queue (DLQ) for malformed events
  • Retry policy with exponential backoff
  • Replication slot lag monitoring with automated alerts

CDC + AI Agents: Event-Driven Automation​

OpenCLAW ADL supports CDC-based agent triggers directly:

New row in support_tickets (op: INSERT)
↓
CDC pipeline fires ADL trigger
↓
SupportTriageAgent wakes with ticket payload
↓
Agent classifies severity, routes to team, creates Jira ticket
↓
Sub-second from DB insert → agent action
CDC Source EventAgent TriggeredAction
orders INSERTOrder processorValidate, enrich, route fulfillment
errors INSERTIncident responseClassify severity, page on-call
leads INSERTLead enrichmentScore, assign sales rep
reviews INSERTSentiment analysisFlag negatives, alert CX team
deals UPDATE → closed_wonRevenue agentUpdate forecast, notify finance

Setting Up a Route​

# Grant replication to CDC user (Postgres)
GRANT REPLICATION SLAVE ON *.* TO 'openclaw_cdc'@'%';
SELECT pg_create_logical_replication_slot('openclaw_slot', 'pgoutput');

Then define the route:

{
"source": "postgres-production",
"tables": ["orders", "customers", "support_tickets"],
"sinks": [
{ "type": "snowflake", "dataset": "raw_events" },
{ "type": "adl", "trigger_agents": ["order-processor", "support-triage"] }
],
"dlq_enabled": true
}

Polling vs CDC: Summary​

PollingCDC
LatencyN secondsSub-second
Database loadHigh (repeated scans)Minimal (log reads)
Captures deletes❌✅
Misses eventsYesNo
App changes neededSometimesNever
Multi-sink fan-outComplexFirst-class

OpenCLAW ships 104 source connectors, 13 sink types, DLQ support, and native ADL agent triggers. If you're still polling, CDC is the upgrade your architecture needs.


Related: How to Trigger an AI Agent From a Database Event · OpenCLAW Pipeline Route Reference