The one Salesforce feature that emits without being asked
Most ways of getting data out of Salesforce require you to say when: a workflow criteria, a Flow trigger, publish code in Apex. Change Data Capture inverts that. Tick an object in Setup → Change Data Capture and the platform publishes an event for every create, update, delete, and undelete on that object - no matter where the change came from: the UI, the API, the data loader, a managed package, a Flow. That completeness is CDC's whole appeal, and why it's the right foundation for data sync, audit trails, cache invalidation, and real-time integrations.
(Deciding between CDC and Platform Events? They ride the same bus but answer different questions - here's the comparison. Short version: PE is for business signals you publish yourself, and CDC is for record changes, published for you.)
What a change event actually contains
Each event carries a ChangeEventHeader (the object type, the change type - CREATE / UPDATE / DELETE / UNDELETE - the record IDs, the list of changed fields, and a replay ID for resuming the stream) plus the changed field values themselves. Two properties surprise people:
| Property | What it means in practice |
|---|---|
| Changed fields only | An UPDATE event carries the fields that changed, not the whole record. If your consumer needs the full current state, it re-fetches over the REST API, or uses a delivery layer that does. |
| Events can coalesce | One event can reference multiple record IDs when similar changes happen in one transaction, so consumers must treat record_ids as a list, not a scalar. |
| At-least-once, unordered | The bus guarantees delivery at least once, not exactly once, and not in order. Idempotent consumers keyed on record ID + timestamp are the pattern. |
The operational realities nobody puts in the quickstart
The 72-hour replay window. The event bus retains events for about 72 hours. Your subscriber checkpoints a replay ID so restarts resume instead of rewinding. If it's down past the window, the position expires and the missed events are gone. A production subscriber needs continuous checkpointing, liveness monitoring, and an honest answer for "what did we miss?" when a gap occurs.
Gap and overflow events. Under certain conditions the bus emits GAP_CREATE/GAP_UPDATE/OVERFLOW events that carry record IDs but no field data. Forward them as-is and your consumers receive empty changes. Handling them properly means re-fetching the live record over REST and merging. Details in our write-up of the Pub/Sub API's failure modes.
Allocations. Editions come with event-delivery and entity-selection allocations, expandable with add-ons, so check yours in Setup before planning a high-volume rollout. And CDC requires an API-enabled edition.
Your options for consuming the stream
| Consumer | How it works | What you own |
|---|---|---|
| Pub/Sub API (current) | gRPC over HTTP/2, Avro-encoded events, explicit replay management | The subscriber: connection lifecycle, schema decoding, checkpointing, retries, monitoring - the full checklist |
| Streaming API / CometD (legacy) | Long-polling Bayeux protocol, older clients | Same responsibilities, older transport - Salesforce steers new work to Pub/Sub |
| Warehouse ETL tools | Managed pipelines replicate objects into an analytics store | Great for BI, but your application never hears about changes |
| SFHooks | We run the Pub/Sub subscriber. Each change arrives at your endpoint as an HMAC-signed JSON webhook, retried up to 31 times, dead-lettered and replayable, logged per event | One HTTPS endpoint and four lines of signature verification |
If your destination is a warehouse, use an ETL tool - that's its job. If your destination is your own code, you want the event itself, verified and reliably delivered.
See a change event as a webhook
The fastest way to understand CDC is to look at one delivery: the playground shows a real SFHooks payload (object, change type, changed fields, record data) and computes its HMAC-SHA256 signature live in your browser. No account needed. When you do connect an org, a built-in test event pushes a synthetic payload through the real pipeline so you can verify your consumer before touching production data.
Frequently asked
What is Salesforce Change Data Capture?
Change Data Capture (CDC) is Salesforce's built-in record-change stream: enable it for an object and the platform automatically publishes an event for every create, update, delete, and undelete, including changes made by the API, data loader, flows, and other packages. You don't write any publishing code, but you do need a subscriber to consume the stream.
How long does Salesforce retain CDC events?
About 72 hours. A subscriber stores a replay ID to resume where it left off, but if it's down longer than the retention window, the saved position expires and events published during the outage can no longer be replayed. Production subscribers need continuous checkpointing and monitoring for exactly this reason.
Do I need to write code to use Change Data Capture?
Enabling it is declarative (Setup → Change Data Capture). Consuming it is not: you need a long-lived subscriber against the Pub/Sub API (gRPC + Avro) or the older streaming API, or a service like SFHooks that runs the subscriber and delivers each change to your endpoint as a signed JSON webhook.
Is Change Data Capture the same as CDC for data warehouses?
Same concept, different scope. Warehouse CDC pipelines (the Fivetran/Airbyte category) replicate tables into analytics stores, often using Salesforce CDC under the hood. If your goal is reacting to changes in your own application (sync, automation, cache invalidation), you want the event stream delivered to your code, which is what webhooks are for.