Data Engineering

CDC vs ETL: When Postgres Changes Should Feed Real-Time Analytics

Decide whether PostgreSQL changes should use CDC, scheduled ETL or direct events for warehouses, event streams and real-time analytics APIs.

1Source of truth
2Freshness SLA
3Change model
4Analytics store
5API/user

The decision rule

Use Postgres CDC for real-time analytics when PostgreSQL remains the source of truth, updates and deletes matter, and decisions improve with seconds-level freshness. Use scheduled ETL when data can be minutes or hours old, tables are manageable and operational simplicity has more value than continuous delivery. Write events directly to the analytical stream when they are analytics-only facts that do not belong in the transactional database.

CDC reduces repeated extraction work, but it does not eliminate data engineering. It replaces scheduled source queries with a continuous change stream. Teams still need an initial backfill, schema policy, modeling, observability, reconciliation and a destination designed for the query workload.

The best architecture is often hybrid: backfill history in bulk, keep mutable operational tables current with CDC, and send new clickstream or telemetry events directly.

Measure freshness where a user consumes the result. Source lag, broker lag and ingestion can all look healthy while a materialization or API remains stale. A useful objective therefore begins at the PostgreSQL commit and ends at the dashboard or endpoint, with reconciliation proving that speed has not replaced completeness.

CDC and ETL solve different timing problems

Traditional batch ETL or ELT runs on a schedule. It queries source tables or exports files, copies a bounded set of data and transforms it for analysis. The job has a clear start and finish, making it simple to reason about and rerun. Its freshness is limited by the schedule and runtime.

CDC reads the database's change log continuously. After an initial snapshot, it transfers only new inserts, updates and deletes. That reduces the need to scan the same source rows repeatedly and can make changes queryable within seconds. The pipeline, however, is always on. Lag, retained WAL and schema errors become operational state.

Neither approach determines where transformations run. CDC events can be transformed in a stream, broker consumer or analytical destination. Batch exports can land raw and be transformed later. The decision is primarily about capture and freshness.

When Postgres CDC is the right choice

Choose CDC when operational users need fresh state: order operations, inventory, fraud review, customer-facing usage dashboards, support queues or feature entitlements. These cases often include updates and deletes and cannot tolerate a nightly view.

CDC also helps when analytical queries are hurting the transactional workload. Instead of repeatedly scanning PostgreSQL for dashboards, stream changes to a columnar analytical store and serve queries there. PostgreSQL remains optimized for transactions while the destination handles aggregations and concurrency.

Event streams are valuable when several downstream systems need the same changes independently. Kafka or another durable broker can buffer outages, support replay and isolate consumers. Do not add a broker only because the architecture diagram looks mature; direct managed replication may be sufficient for one destination.

When scheduled ETL is the better design

Batch wins when the business decision happens daily, when source tables are small, when data must be reconciled before it is meaningful or when the team cannot justify continuous pipeline operations. Finance close, periodic compliance extracts and slowly changing reference tables often do not need a streaming path.

An indexed watermark query can efficiently copy append-only rows. A periodic full replacement can be the safest model for a small dimension table because it avoids complex update semantics. If hard deletes never occur and late updates are bounded, incremental ETL may satisfy the requirement with fewer failure modes.

Beware of “poor man's CDC” built only on updated_at. Application clocks, missed timestamp updates, equal timestamps and hard deletes can create gaps. If using a watermark, define overlap and deduplication, use a monotonic key where possible and run reconciliation.

When CDC should not be the first event stream

Some events do not belong in PostgreSQL. Page views, button interactions, service telemetry, logs and high-volume product usage may exist only for analytics. Writing them to a transactional table and immediately extracting them with CDC adds storage, WAL and an unnecessary dependency on the primary database.

If application code controls the event, publish it directly to a durable ingestion endpoint or stream. Give it a stable ID, schema version and event timestamp. Keep authoritative business outcomes—paid invoice, account state, shipment status—in the transactional source and capture those changes through CDC if downstream freshness is required.

Dual writes need a failure model. An application that separately commits Postgres and publishes an event can succeed at one and fail at the other. An outbox table written in the same transaction, then captured through CDC, is useful when the application needs deliberate domain events with transactional consistency.

Three practical architecture patterns

1. Bulk backfill plus CDC tail

Copy historical rows using a snapshot or file export, record a consistent source position and then consume changes after that point. This is the normal choice for a large mutable table that must become current without replaying years of WAL.

2. Postgres to Kafka to real-time analytics

A connector reads logical changes, Kafka distributes them and the analytical destination models current state or change history. This fits multiple consumers, durable replay and high-change workloads.

3. Direct events plus periodic dimensions

Send high-volume behavioral events directly while copying customer, plan or account dimensions periodically from PostgreSQL. This avoids CDC where source changes are slow and keeps the event path independent.

Choosing a managed service and destination

A managed CDC service can operate the source connector, transport or destination delivery, but “managed” covers different boundaries. Ask who owns the replication slot, broker, offsets, schema registry, quarantine, backfill and incident response. Check regions, private networking, encryption and deletion requirements.

For real-time analytics, Tinybird documents both scheduled PostgreSQL copies and a CDC path. Its migration decision guide recommends periodic imports for smaller or less time-sensitive data and CDC through Kafka-compatible infrastructure for continuously changing tables that need seconds-level freshness. Once modeled, SQL Pipes can expose the data through analytical API endpoints.

For analytics-only events, Tinybird's Events API is an alternative to routing them through PostgreSQL. That distinction keeps the architecture honest: CDC for transactional changes; direct event capture for new analytical facts.

Decision matrix

RequirementPreferReason
Updates/deletes in secondsCDCContinuous log-based capture
Append-only, hourly freshnessIncremental ETLLower operational complexity
Small dimension, daily refreshFull replacementSimple and reconcilable
Clickstream or telemetryDirect eventsAvoids unnecessary Postgres writes
Transactional domain eventOutbox + CDCConsistent with database commit
Several independent consumersCDC + brokerDurable fan-out and replay

FAQ

How does Postgres CDC reduce ETL?

It replaces repeated extraction scans with incremental log reading and continuously delivers changes. Transformation, modeling, quality checks and destination operation still remain.

Can Postgres CDC feed customer-facing analytics?

Yes, when changes are delivered to an analytical store that handles updates, deletes, deduplication and concurrent API queries. Do not run every customer dashboard directly against the production OLTP database.

When should CDC feed an event stream?

Use a stream when multiple consumers, buffering, replay or independent scaling justify it. For one managed destination, a direct connector may be simpler.

Sources checked September 5, 2026: PostgreSQL logical-decoding documentation and Tinybird guidance for migrating PostgreSQL analytical workloads, Kafka ingestion and direct event ingestion.