Change Data Capture Explained: Real-Time Database Sync Without the Polling Tax
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:
| Problem | Impact |
|---|---|
| Latency | N-second delay minimum — worse at load |
| Database load | Full table scans on every poll cycle |
| Missed deletes | updated_at doesn't change on DELETE |
| Race conditions | High-frequency updates between polls create gaps |
| Thundering herd | All 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:
- Zero application changes — CDC reads the log directly, no code changes needed
- Complete change fidelity — every operation is captured, including deletes
- 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 Event | Agent Triggered | Action |
|---|---|---|
orders INSERT | Order processor | Validate, enrich, route fulfillment |
errors INSERT | Incident response | Classify severity, page on-call |
leads INSERT | Lead enrichment | Score, assign sales rep |
reviews INSERT | Sentiment analysis | Flag negatives, alert CX team |
deals UPDATE → closed_won | Revenue agent | Update 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
| Polling | CDC | |
|---|---|---|
| Latency | N seconds | Sub-second |
| Database load | High (repeated scans) | Minimal (log reads) |
| Captures deletes | ❌ | ✅ |
| Misses events | Yes | No |
| App changes needed | Sometimes | Never |
| Multi-sink fan-out | Complex | First-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