Broken history often stays hidden until remediation or skilled-person reviews. Why? Event-driven Change Data Capture fundamentally changes how history behaves in a data platform. When Financial Services organisations move from batch ingestion to streaming CDC, long-standing SCD2 assumptions quietly break — often without immediate symptoms. Late, duplicated, partial, or out-of-order events can silently corrupt Bronze history and undermine regulatory confidence. This article sets out what “correct” SCD2 means in a streaming world, why most implementations fail, and how to design Bronze pipelines that remain temporally accurate, replayable, and defensible under PRA/FCA scrutiny in 2025–2026.
Contents
- Contents
- 1. Introduction: Why Streaming CDC Breaks SCD2
- 2. The Five CDC Failure Modes That Corrupt Bronze
- 3. What “Correct SCD2” Means in a CDC World
- 4. Designing an Event-Driven SCD2 Pipeline
- 5. Ordering: The Hardest Problem
- 6. Event Normalisation & CDC Canonical Models
- 7. Processing Semantics (Exactly-Once, Idempotency)
- 8. Temporal Repair, Replay & Backfill
- 9. Platform Patterns
- 10. Regulatory Expectations
- 11. Summary
1. Introduction: Why Streaming CDC Breaks SCD2
The definitive guide to building event-driven SCD2 Bronze pipelines that withstand PRA/FCA scrutiny and real-world upstream chaos. How UK Financial Services avoid silently corrupting history when moving from batch ingestion to streaming change data capture. As UK Financial Services organisations modernise core platforms, the shift from batch ingestion to event-driven Change Data Capture (CDC) is inevitable. But most implementations break SCD2 history, often silently, through late, out-of-order, duplicated, or partially ordered events. This article explains how to build regulator-defensible, temporally correct SCD2 Bronze tables from CDC streams — whether using Debezium, Kafka, MSK, Pulsar, GoldenGate, SQL Server CDC, Oracle redo logs, Snowflake Streams, or Databricks Auto Loader. We cover event normalisation, ordering windows, operation semantics, merge logic, idempotency, temporal repair, and replay — the hard realities required to keep Bronze clean, correct, and fully auditable in a UK FS environment.
Most UK FS organisations built their Bronze layers on batch ingestion, where:
- files or extracts arrive in order
- transformations run as deterministic batches
- SCD2 merges operate on well-behaved, complete datasets
CDC breaks these assumptions.
Streaming CDC introduces:
- unordered events
- duplicated messages
- partial row updates
- snapshot + log interleaving
- late or missing events
- schema drift in motion
When these flows hit a naive SCD2 merge pipeline, the result is predictable:
- incorrect effective periods
- inverted historical timelines
- missing versions
- duplicated versions
- temporal gaps
- “current” flags wrong
- PIT reconstruction impossible
- silent corruption
Many banks discover these issues only during:
- Consumer Duty lookbacks
- remediation reviews
- AML investigations
- PRA/FCA skilled-person (s166) reviews
Because regulators increasingly require:
“Show me the exact state as known on <date> based on the data you held at the time.”
This is impossible without correct event-driven SCD2.
This article is written for data engineers, architects, and risk-aligned platform owners in UK Financial Services who are already using CDC or planning to migrate from batch ingestion. It assumes familiarity with SCD2, streaming platforms, and regulated data environments.
2. The Five CDC Failure Modes That Corrupt Bronze
Before discussing solutions, it’s critical to understand how CDC actually fails in production. These failure modes are not edge cases or tooling bugs — they are normal behaviours of distributed systems operating at scale. Each one breaks a different assumption that traditional SCD2 logic relies on, and together they explain why Bronze history often looks correct until it is challenged. The following patterns are consistently observed across UK FS platforms, regardless of vendor or architecture.
These patterns appear in every FS platform that attempts streaming CDC.
2.1 Late Events
An update from 14:02 arrives at 14:20 — after later updates have applied.
Impact:
- SCD2 history is wrong
- effective periods reversed or incorrect
- downstream Silver/Gold models drift
2.2 Out-of-Order Events
Event order: Update #3 → Update #1 → Update #2
Common in:
- Debezium
- Oracle GoldenGate
- SQL Server CDC
- multi-partition Kafka topics
2.3 Duplicated Events
Because of retries, consumer failover, or upstream connectors.
If pipelines are not idempotent → duplicate SCD2 versions appear.
2.4 Partial Updates
CDC often sends only the fields that changed.
If SCD2 logic assumes full rows →
you resurrect stale attributes and corrupt history.
2.5 Upstream Backfills
A core system corrects historical data, sends years of changes into a stream, and destroys your SCD2 ordering if not handled properly.
These failure modes are universal.
Correct pipelines must expect — not avoid — them.
3. What “Correct SCD2” Means in a CDC World
In batch systems, “correct” SCD2 is usually defined operationally: merges succeed, current flags look right, and row counts balance. Streaming CDC forces a stricter definition. Correctness becomes a temporal property, not a procedural one. This section defines what correctness actually means when events arrive late, out of order, or more than once — and why those properties are non-negotiable in regulated environments.
With streaming CDC, “correct” has a specific meaning:
- Temporal correctness
- versions reflect the true event order
- effective_from == event timestamp
- effective_to reflects next known change
- Idempotency
- running the same events twice produces the same Bronze state
- Deterministic reprocessing
- replaying CDC for any period reproduces the same SCD2 versions
- Late event handling
- Bronze inserts missing history in the correct place
- adjusting affected effective_to windows
- Merge-safe semantics
- operations do not clobber earlier/later versions
- partial updates are reconciled correctly
In short:
Correct SCD2 from CDC means Bronze remains a reliable time machine.
This is essential in UK FS where history must be legally defensible.
In this article, “Bronze” refers to the lowest curated, queryable layer that downstream analytics and regulatory reporting depend on and not a raw landing zone.
4. Designing an Event-Driven SCD2 Pipeline
Once correctness is defined, architecture must follow. An event-driven SCD2 pipeline cannot be a simple extension of batch design with a streaming trigger bolted on. It requires explicit stages for ordering, interpretation, and repair. This section outlines the minimum structural components required to absorb CDC chaos while preserving Bronze as a reliable historical record.
A mature pipeline has these components:
- Raw CDC Landing (append-only)
- Event Normalisation
- Ordering Buffer / Watermarking
- Change Interpretation Layer
- Hybrid SCD2 (delta_log + periodic merge)
- Temporal Repair Path
- Reprocessing & Replay Mechanisms
Let’s walk through them.
5. Ordering: The Hardest Problem
Every CDC discussion eventually collapses into the same question: what is the correct order of events? Arrival order is unreliable, and source systems rarely provide a single perfect clock. Ordering is therefore not a configuration choice but a design responsibility. This section explores how order can be inferred, stabilised, and corrected — and why buffering and repair are unavoidable in any serious implementation.
CDC event order is not guaranteed.
To build correct SCD2, we must impose order manually.
5.1 Use Source-Generated Timestamps Where Available
Best sources:
- Oracle SCN
- SQL Server LSN
- CDC commit timestamps
- Debezium
ts_ms
5.2 If Not Available → Composite Ordering
Use a tuple to order:
(event_source_commit_ts, op_order, connector_offset)
5.3 Watermarking & Ordering Buffers
You cannot apply events as they arrive.
You must buffer until “enough time has passed” to assume ordering is stable.
For example:
- 1–5 minutes for transactional systems
- 15–60 seconds for low latency needs
- configurable per domain
Ordering buffers introduce deliberate latency; in regulated domains this is usually a conscious trade-off in favour of temporal correctness, with SLAs defined per domain rather than globally.
5.4 Out-of-Order Correction
If a late event arrives outside the buffer:
- insert historical version
- adjust effective_to on the next version
- re-write affected windows
Which is why Bronze must support temporal repair.
6. Event Normalisation & CDC Canonical Models
CDC tools emit change events in wildly different shapes, semantics, and levels of completeness. Attempting to apply SCD2 logic directly to these raw structures quickly becomes unmanageable. Normalisation is the step that turns vendor-specific change messages into something the platform can reason about consistently. This section explains why a canonical CDC model is essential before any SCD2 logic is applied.
Every CDC tool emits different structures. Normalising into a single schema simplifies SCD2 immensely.
A typical canonical CDC structure:
| field | meaning |
|---|---|
| business_key | stable identifier |
| op_type | INSERT / UPDATE / DELETE |
| event_ts | event timestamp at source |
| commit_ts | transaction commit time |
| payload | changed fields only |
| full_after | full row after change (if available) |
| full_before | full row before change (if available) |
| batch_id | lineage |
| source_system | system of origin |
6.1 Partial Updates
If payload = only changed fields, you must reconstruct full state:
- join to last known Bronze record
- patch fields
- compute new hashes
- only emit new SCD2 record if fields have meaningfully changed
6.2 Delete Handling
CDC often treats deletes inconsistently:
- soft deletes
- hard deletes
- tombstone messages
- nullified rows
- logical deletes (status_flag)
All must be mapped to a consistent SCD2 pattern:
- “delete” → effective_to = event_ts
- or “soft delete” → add deletion_flag and continue
7. Processing Semantics (Exactly-Once, Idempotency)
Streaming platforms promise strong guarantees, but those guarantees are often misunderstood. In practice, Bronze correctness depends less on delivery semantics and more on how writes behave under replay, duplication, and failure. This section reframes processing guarantees in practical terms, focusing on idempotency and determinism rather than theoretical exactly-once delivery.
7.1 Exactly-Once is a Myth
In streaming systems, exactly-once means:
- at-least-once delivery
- plus idempotent processing
- plus de-duplication
- plus transactionally committed writes
7.2 Idempotent SCD2 Logic
Bronze merges must behave correctly even when:
- events replay
- consumers restart
- partitions rewind
- connectors resend old changes
Use:
- deterministic SCD2 versioning
- hashes to detect no-op updates
- unique keys per SCD2 version:
(business_key, effective_from)
7.3 Deduplication
Before SCD2 merge, remove duplicates:
- based on (business_key, event_ts, payload_hash)
- OR via unique staging tables with merge semantics
8. Temporal Repair, Replay & Backfill
Most SCD2 designs assume history is written once and never revisited. CDC breaks that assumption permanently. Late events, corrections, and backfills require history to be reopened and adjusted — sometimes years later. This section addresses the mechanisms needed to repair time safely, replay events deterministically, and rebuild Bronze without destroying trust in historical outputs.
This is where most platforms fall over — and where the UK PRA/FCA will focus during a review.
8.1 Late Events
When a late event arrives:
- locate correct temporal position
- insert new SCD2 row
- shift existing windows
- recalculate effective_to
8.2 Out-of-Order Fixes
If correction events occur (common in KYC, CRM):
- close earlier versions
- open new ones
- ensure PIT is consistent
8.3 Backfill / Reprocessing
Every FS organisation must be able to:
- discard 6 months of Bronze
- replay all CDC events
- rebuild deterministically
If this is impossible, SCD2 cannot be trusted.
8.4 Retroactive Schema Changes
If a new field appears upstream:
- add column
- backfill historical state where possible
- maintain version stability
9. Platform Patterns
While the principles of event-driven SCD2 are platform-agnostic, the mechanics are not. Different ecosystems impose different constraints around ordering, state management, and merge semantics. This section maps the earlier concepts onto common FS platforms, highlighting where additional care is required and where native features can be leveraged safely.
9.1 Databricks / Delta Lake
Use:
- Auto Loader for incremental CDC ingestion
- Delta Live Tables or structured streaming with watermarking
- Delta Change Data Feed for incremental SCD2 merges
- Hybrid strategy:
- delta_log for incoming updates
- periodic merges into Bronze
Newer managed CDC features (e.g. declarative pipelines with APPLY CHANGES) can reduce implementation effort, but they do not remove the underlying requirements around event-time ordering, late data handling, or determinism. Teams must still understand and validate the temporal semantics being applied.
9.2 Snowflake
Use:
- Snowflake Streams (capturing change events)
- Tasks for incremental application
- MERGE logic using QUALIFY + ROW_NUMBER
- Variant column for partial/full payloads
Ensure Streams + Tasks do not apply events in event-time order unless you enforce it.
9.3 Kafka + Debezium + Iceberg/Hudi
- Debezium → Kafka (unordered)
- Use Flink/Spark for ordering buffers and normalisation
- Write to Iceberg/Hudi Bronze using incremental upserts
- Hybrid merges for correctness
10. Regulatory Expectations
Regulators do not assess data platforms by their architecture diagrams — they assess them by the questions they can and cannot answer. CDC-driven SCD2 introduces new risks that are increasingly visible during skilled-person reviews and remediation exercises. This section translates technical design choices into the evidence, explanations, and assurances that UK regulators now expect to see.
Regulators increasingly require:
- evidence that SCD2 Bronze is correct in event-time order, not arrival order
- the ability to answer:
“What did you know at time X?” - clear lineage from Bronze back to raw CDC events
- deterministic rebuild capability
- documented rules for late/out-of-order correction
- fully explainable effective windows
A broken CDC→SCD2 implementation is invisible until the moment a regulator asks for history.
Fixing it after the fact is usually impossible.
11. Summary
Event-driven CDC is not optional for modern FS platforms, but it is unforgiving of legacy assumptions. The final section consolidates the architectural, temporal, and regulatory implications discussed throughout the article, reinforcing what must be true for Bronze to remain trustworthy. The focus is not on tools, but on the properties a platform must exhibit to survive scrutiny in the years ahead.
Event-driven CDC is the future — but only works if SCD2 is re-designed for a world where:
- events arrive late
- in the wrong order
- with partial data
- sometimes duplicated
- occasionally years out of date
A mature SCD2 Bronze for UK FS must support:
- Raw CDC landing with full lineage
- Event normalisation into a canonical structure
- Ordering buffers & watermarks
- Hybrid SCD2 merges for correctness at scale
- Idempotent processing
- Temporal repair & PIT rebuild
- Incremental + replayable architecture
- Regulator-defensible lineage
This is the unavoidable next stage in the evolution of FS data platforms.
Handled correctly, event-driven CDC produces Bronze tables that are trustworthy, auditable, and fit for the regulatory environment of 2025–2026 and beyond.