Telemetry
Database reliability SQL recipe

Measure Database Replication and CDC Lag

Compare replica and change-data-capture consumers by average lag, worst lag, bytes behind, and stale-sample rate.

Beginnerdatabase_replication_samplesReviewed 2026-07-28Tested with Apache DataFusion 45.2.0

Reviewed by the Telemetry product team on . SQL compatibility, event contract, synthetic output, and operational caveats. Editorial ownership

Question answered

Which replicas or CDC consumers are falling behind their source database?

Replication is healthy only when downstream consumers remain current enough for their purpose. Measuring both seconds and bytes behind keeps a quiet stalled consumer distinguishable from a busy one processing a larger stream.

Event contract

Fields the query expects

FieldTypeWhy it exists
timestamp_utcTimestampReplication sample time in UTC.
consumer_nameUtf8Stable replica, connector, or downstream consumer name.
source_typeUtf8postgres_replica, cdc_pipeline, or another controlled source type.
regionUtf8Approved deployment region.
lag_secondsFloat64Observed time lag behind the source.
replay_bytes_behindInt64Approximate bytes waiting to be replayed or consumed.
statusUtf8healthy, lagging, stalled, or unavailable.
environmentUtf8Deployment environment.
DataFusion SQL

Copy the query

sql
SELECT
  consumer_name,
  source_type,
  region,
  COUNT(*) AS samples,
  AVG(lag_seconds) AS average_lag_seconds,
  MAX(lag_seconds) AS maximum_lag_seconds,
  MAX(replay_bytes_behind) AS maximum_bytes_behind,
  SUM(CASE WHEN lag_seconds > 30 THEN 1 ELSE 0 END) AS stale_samples,
  100.0 * SUM(CASE WHEN lag_seconds > 30 THEN 1 ELSE 0 END)
    / NULLIF(COUNT(*), 0) AS stale_sample_rate_pct
FROM database_replication_samples
WHERE timestamp_utc >= now() - INTERVAL '24 hours'
  AND environment = 'production'
GROUP BY consumer_name, source_type, region
HAVING COUNT(*) >= 10
ORDER BY maximum_lag_seconds DESC;

This read-only query is planned and executed against an empty typed table with Apache DataFusion 45.2.0. The deterministic sample output is synthetic and reviewed separately; validate field types, thresholds, and business definitions against your own data. Read the testing methodology.

Query result

Maximum replication or CDC lag

The west-region replica exceeds the illustrative thirty-second freshness threshold in two samples.

consumer_namesource_typeregionsamplesaverage_lag_secondsmaximum_lag_secondsmaximum_bytes_behindstale_samplesstale_sample_rate_pct
replica-us-westpostgres_replicaus-west1214.584244,040,192216.67
billing-cdccdc_pipelineus-east12366,291,45600

Synthetic example output. Run the query against your own event schema and thresholds before using it for operational decisions.

Maximum replication or CDC lag: static chart of synthetic maximum_lag_seconds values from the Measure Database Replication and CDC Lag example result
Indexable SVG of the deterministic example output. Download it for an article, runbook, or design review with attribution.

Reproduce the example

Download the public fixture

The JSON bundle includes the typed event contract, reproducible input rows, exact SQL, expected output, review notes, and engine version. The CSV contains the displayed result.

How the SQL works

  1. 1Average lag describes the normal state while maximum lag preserves short but consequential stalls.
  2. 2A stale-sample rate is easier to alert on than one isolated maximum.
  3. 3Bytes behind supplies workload context because the same delay can represent very different amounts of replay work.

Edge cases to decide

  • Database lag fields can mean write, flush, replay, or connector delay. Name the measured boundary.
  • A quiet source can report low bytes behind while still being stale; keep both time and volume.
  • Use a workload-specific freshness objective rather than one global thirty-second threshold.

Recommended dashboard

  • Bars: maximum_lag_seconds by consumer
  • Trend: lag_seconds and replay_bytes_behind
  • Table: newest lagging or unavailable consumers

Alert guidance

Alert when a consumer exceeds its documented freshness objective for consecutive samples or stops reporting entirely.

Read alert setup

Put the recipe to work

Related instrumentation and guides

Continue the analysis

Run it on real events

Create a table, adapt the fields, and save the result

Start free, send structured events, and use the query result as a chart, shared dashboard widget, or alert input.

Get an API key