TL;DR
- Platform Events carry a message you design: "Order Shipped", "Payment Failed". You choose the fields and when to publish.
- Change Data Capture (CDC) carries a message Salesforce generates whenever a record is created, updated, deleted or undeleted. You choose which objects, not what the message says.
- Event Relay moves platform events and change events out of Salesforce into Amazon EventBridge. It does not create events of its own, and it only goes one way.
- They share one delivery allocation. Every Pub/Sub API client, CometD client and event relay that receives an event counts against it. Apex triggers and Flows do not.
- Flows cannot subscribe to change events. If the subscriber is a Flow, you need a platform event.
- Standard volume platform events reach end of life on 15 December 2026. Any design still using them needs a migration date before it needs a new subscriber.
What You'll Learn
- What each of the three actually does, and why they sit at different layers
- A side-by-side comparison of payload, retention, ordering, subscribers and cost
- When to choose Platform Events, when to choose CDC, and when Event Relay is the right transport
- How delivery allocations work across all three, and the cheapest way to reduce them
- The legacy options (PushTopics, Generic Streaming, Outbound Messages) and what replaces them
- Three worked scenarios with the choice and the reasoning
The Problem
Salesforce offers three event features with overlapping names and overlapping documentation, and most comparisons put them in one table as if you pick one. That framing causes bad designs. Teams build a platform event that copies every field of an Account on every save, which is CDC done by hand and done badly. Or they turn on CDC for Opportunity so a downstream system can learn that a deal was won, then make that system work out "won" from a stream of field changes.
The three are not substitutes at the same layer. Two of them produce events and one of them carries events somewhere else. Once you know which layer each sits in, most decisions are straightforward. The hard choices left are about cost and limits.
Common questions this article answers:
- Should my integration listen for record changes, or should my org announce business events?
- Can a Flow subscribe to Change Data Capture?
- Does Event Relay replace MuleSoft or my middleware, and does it work in both directions?
Quick Answer
Ask three questions in order.
1. Who decides what the message says?
- You do, because it describes a business moment ("Order Shipped") with exactly the fields the subscriber needs: Platform Event.
- Nobody needs to, because the subscriber wants every change to a record so it can keep its own copy in sync: Change Data Capture.
2. Who is subscribing?
- A Flow: Platform Event. Flows do not subscribe to change events.
- An Apex trigger: either works. Change event triggers run asynchronously after the transaction commits.
- An external system: either works, through Pub/Sub API (or CometD for older clients).
3. Where does the event need to end up?
- Amazon EventBridge (Lambda, Step Functions, SQS and the rest of AWS): add Event Relay on top of whichever event you chose. No middleware needed.
- Anywhere else: an external client subscribes through Pub/Sub API directly, or through your integration platform.
| If you need... | Use |
|---|---|
| A business event with a payload you control | Platform Event |
| Record replication to a warehouse, cache or second system | Change Data Capture |
| Salesforce events in AWS without middleware | Event Relay + one of the above |
| A Flow to react to something happening | Platform Event |
| An external system to publish into Salesforce | Platform Event, published through Pub/Sub API or REST API |
The same three questions as an interactive picker:
Who decides what the message says?
Two producers, one transport
Start with who decides what the message says. The panel gives the mechanism to use and the limit that will matter first.
The Three Layers
It helps to separate what produces the event, how a subscriber receives it and where it is carried.
| Layer | What sits here |
|---|---|
| Producers | Platform Events (you publish them), Change Data Capture (Salesforce publishes them when records change) |
| Subscription APIs | Pub/Sub API (gRPC, the current API), CometD / Streaming API (older Bayeux protocol), empApi in Lightning components |
| Transport out of Salesforce | Event Relay (to Amazon EventBridge) |
| In-org subscribers | Apex triggers (both producers), Flows (Platform Events only) |
Both producers write to the same event bus. Every event gets a ReplayId, sits on the bus for a retention window, and can be read by any subscriber that has access to its channel. Event Relay is a subscriber too: a managed one that Salesforce runs for you, which reads from a channel and forwards each event to an EventBridge partner event source in your AWS account.
That is why "Platform Events or Event Relay?" is the wrong question. Event Relay needs something to relay.
The figure shows each journey across the bus. Red hops are the ones that spend your delivery allocation.
Same bus, three journeys
Platform events and change events share one bus and one delivery allocation. Point at each hop to see what happens and whether it counts.
Red hops count against your delivery allocation. In-org subscribers never do.
Side-by-Side Comparison
| Platform Events (high volume) | Change Data Capture | Event Relay | |
|---|---|---|---|
| What it is | A message type you define, like a custom object without storage | A message Salesforce generates for record changes | A managed forwarder from a Salesforce channel to EventBridge |
| Who defines the payload | You (custom fields on the __e object) |
Salesforce (changed fields plus a ChangeEventHeader) |
Not applicable: it forwards the event as published |
| When an event is published | When your Apex, Flow or API call publishes it | On create, update, delete and undelete of a selected object | Not applicable |
| Retention on the bus | 72 hours | 3 days | Not applicable |
| Ordering | Guaranteed only within a single publish call | Follows the order of committed transactions | Not applicable |
| Apex trigger subscribers | Yes | Yes, asynchronous after commit | Not applicable |
| Flow subscribers | Yes | No | Not applicable |
| External subscribers | Pub/Sub API, CometD | Pub/Sub API, CometD | It is the external delivery |
| Selection limit | None specific | 5 entities by default; an add-on removes the cap | Configured per channel |
| Counts against delivery allocation | Yes, per external client | Yes, per external client | Yes |
| Editions | Enterprise, Performance, Unlimited, Developer (not Professional or Group) | Enterprise, Performance, Unlimited, Developer | Depends on the events it relays |
Ordering. Platform events are delivered to subscribers in ReplayId order, but if your code makes two separate publish calls, Salesforce does not guarantee the bus orders them the way you called them. If order matters, publish the related events in one call. CDC follows the order in which transactions committed, and changes from the same transaction share a transactionKey and carry a sequenceNumber.
Duplicates. Platform event publishing is at-least-once. A subscriber can receive the same event twice, with the same EventUuid and a different ReplayId. Every subscriber that does something it cannot repeat (send an email, post a payment) should deduplicate on EventUuid.
When to Use Platform Events
Choose a platform event when the subscriber cares about a business moment, not about the state of a record.
Good examples:
Order_Shipped__ewith the order number, carrier and tracking number: exactly what the warehouse portal and the customer notification service need, nothing morePayment_Failed__epublished by an external payment gateway into Salesforce, which a Flow picks up to create a task for the account ownerCase_Escalated__epublished from an Apex trigger so a dozen different subscribers can react without the trigger knowing about any of them
What you get:
-
A stable contract. You choose the fields, so you can add a field to the Order object without changing what subscribers receive. With CDC, subscribers see whatever changed.
-
Inbound and outbound. External systems can publish platform events into Salesforce through Pub/Sub API or the REST API, and Flows and triggers react. CDC only goes out.
-
Flow support. A platform-event-triggered Flow lets admins build subscribers without Apex.
-
Transaction control. Each event definition has a publish behaviour:
- Publish After Commit publishes only if the transaction commits, and respects rollbacks. Use this for anything that announces a change to data, otherwise subscribers can react to a record that was never saved.
- Publish Immediately publishes even if the transaction later rolls back. Use it for logging and error reporting, where you want the event precisely because the transaction failed.
This setting applies to publishing from Apex and Flow. It does not apply when an external client publishes through Pub/Sub API.
What it costs you:
- You write and maintain the publishing logic. Every place that should announce "Order Shipped" has to publish the event. Miss one path (a data load, a different Flow) and subscribers never hear about it.
- No history beyond 72 hours. A subscriber that is down for four days loses events. Platform events are a notification channel, not a system of record.
When to Use Change Data Capture
Choose CDC when a subscriber needs to keep its own copy of Salesforce records up to date: a data warehouse, a search index, a cache, a second system of record during a migration.
What you get:
- Every change, with no code. Select the object in Setup → Change Data Capture and every create, update, delete and undelete produces a change event, including changes from data loads, integrations and other automation that a hand-built platform event would miss.
- Only what changed. An update event carries the changed fields and a header listing them (
changedFields), thechangeType, therecordIdsand thecommitUser. - Transaction grouping. Several changes in one transaction share a
transactionKey, so a subscriber can apply them together. - Custom objects and many standard objects. All custom objects are supported, plus a documented subset of standard objects.
What you need to know before relying on it:
-
Five entities by default. Without the add-on licence, you can select five objects across all channels. Selections made by installed AppExchange packages do not count against this. Check what you are using with:
SELECT COUNT_DISTINCT(SelectedEntity) FROM PlatformEventChannelMember -
Gap events. Sometimes Salesforce cannot produce a full change event: the event would exceed 1 MB, a field type was converted, an internal error occurred, or data was changed directly in the database. You receive a
GAP_CREATE,GAP_UPDATE,GAP_DELETEorGAP_UNDELETEevent with only the header. Your subscriber has to query the record to find out what changed. A subscriber that ignores gap events silently drifts out of sync. -
Overflow events. After the first 100,000 changes in a single transaction, Salesforce stops sending individual events and sends one
GAP_OVERFLOWevent per entity instead. A large data load in one transaction can produce these. The subscriber needs a resync path. -
No event for some changes. Hard deletes from the Recycle Bin do not produce a change event. Several DML operations on the same record in one transaction produce one event, not several.
-
Formula fields are a partial story. Custom formula and roll-up summary fields are included in change events, but a change to a formula's inputs does not always produce an event for the formula itself, formula fields are not available in Apex change event triggers, and derived system fields such as
LastActivityDateare excluded. If a subscriber depends on a formula value, have it calculate the value from the underlying fields or query the record. -
Flows cannot subscribe. If an admin wants to automate something when an Account changes, a record-triggered Flow is the tool, not CDC.
Enrichment and filtering. On a custom channel, you can add enriched fields (fields included in every update and delete event even when they did not change, such as an external ID the subscriber needs for matching) and filter expressions (only deliver events that match, for example Industry = 'Healthcare'). Both work for Pub/Sub API, CometD and Event Relay subscribers. Neither works for Apex triggers, because triggers do not subscribe through channels.
Data Cloud uses CDC too. Data Cloud CRM connector data streams consume change events through a standard channel called DataCloudEntities. Do not edit that channel through the API, and do not count on Data Cloud being your only CDC consumer when you size delivery usage.
When to Use Event Relay
Choose Event Relay when the destination is AWS and you would otherwise write and host a subscriber whose only job is to forward events to EventBridge.
You configure:
- A named credential that points at your AWS account and region (see migrating legacy named credentials if your org still uses the older type)
- A channel and channel member: the platform event or change events to relay (a custom channel lets you filter and enrich)
- An
EventRelayConfigrecord linking the channel to the named credential
Salesforce then creates a partner event source in your AWS account. You associate it with an event bus and write EventBridge rules to route events to Lambda, Step Functions, SQS or anything else EventBridge supports.
What you need to know:
- One direction only. Event Relay sends events from Salesforce to EventBridge. To go the other way, you build it in AWS: an EventBridge API destination and rule that calls the Salesforce REST API to publish a platform event, authenticated through a connected app. That works, but you build, run and monitor it yourself.
- It counts against your delivery allocation. Each relay is a subscribed client.
- Default AWS regions only. Opt-in AWS regions are not supported.
- Processing location. Salesforce processes relays on Hyperforce in the US, EU, Australia or India, which may not be the region your org runs in. If you have data residency obligations, read Salesforce data sovereignty in New Zealand and check the relay considerations before sending regulated data this way.
- Sandboxes. Relay configurations are not copied when you create or refresh a sandbox. Script them as part of your post-refresh steps.
Pub/Sub API: How External Subscribers Connect
Whichever producer you choose, an external client that is not AWS will almost certainly connect through Pub/Sub API. It is a gRPC API over HTTP/2 that publishes, subscribes and retrieves event schemas (Avro) through one interface, with flow control so a slow client asks for events at the rate it can process them.
Limits that shape client design:
- A subscriber can request up to 100 events per call
- An individual event can be up to 1 MB
- Salesforce recommends publishing up to 200 events per request
- Pub/Sub API is not available in Government Cloud
CometD (the Streaming API) still works, but new integrations should use Pub/Sub API.
Managed event subscriptions move the subscriber's replay position into your org, so you can see and stop a subscriber yourself. They are still in beta. Managed event subscriptions for external subscribers covers when they are worth it.
Delivery Allocations: The Cost All Three Share
High volume platform events and change events share one delivery allocation. It is counted per subscribed client: if three external clients subscribe to the same channel, every event counts three times. Apex triggers, Flows and Process Builder processes are excluded from the count. Pub/Sub API clients, CometD clients, empApi components and event relays are included.
| Edition | Event deliveries (rolling 24 hours) | Event publishing (per hour) |
|---|---|---|
| Unlimited, Performance | 50,000 | 250,000 |
| Enterprise | 25,000 | 250,000 |
| Developer | 10,000 | 50,000 |
Salesforce's allocation tables also list Professional Edition with the API add-on at the Enterprise figures, even though its considerations page says platform events are not supported in Professional Edition. If you are on Professional, confirm with Salesforce before designing around events.
When the delivery allocation runs out, subscribers are disconnected, and that affects every external subscriber in the org, not just the one using the most. An add-on licence adds 100,000 deliveries per day (3 million per month) and 25,000 publishes per hour.
Three ways to spend less, in order of effect:
- Filter on the channel. A filter expression on a custom channel means unmatched events are never delivered and never counted. This is the largest saving available and it is generally available.
- Fewer subscribers. One integration client that fans out internally costs one delivery per event. Five clients cost five.
- Select fewer CDC entities. Every object you add multiplies by every subscriber.
Platform event delivery limits: measure, attribute and cut usage shows how to find which client is spending your allocation, and reducing delivery costs from browser tabs covers the empApi case where each open tab is a separate subscriber.
The Legacy Options and What Replaces Them
You will find these in older orgs. None of them should be the answer for a new design.
| Legacy feature | Status | Replace with |
|---|---|---|
| Standard volume platform events | End of life 15 December 2026. After that date you cannot publish or subscribe. | High volume platform events. See the migration guide. |
| PushTopic events | Legacy, limited support, no new features. 1 day retention, no Pub/Sub API support. | Change Data Capture |
| Generic Streaming events | Legacy, limited support, no new features. | Platform Events |
| Outbound Messages | Mostly configured as Workflow Rule actions, and Workflow Rules reached end of support on 31 December 2025. Sends only the latest record data and drops messages after 24 hours of failed retries. | Platform Events with a Pub/Sub API subscriber, or Event Relay to AWS |
Salesforce's own developer guide still describes the standard volume retirement as Summer '27 in places. The knowledge article Salesforce updated in October 2026 gives 15 December 2026, and that is the date to plan against.
Three Scenarios
Scenario 1: The ERP needs to know when an order is ready to ship.
The ERP does not care that Status__c went from Packed to Ready, or that someone fixed a typo in the shipping address. It needs one message at one moment, with the order number, lines and address.
Choice: a platform event, Order_Ready__e, published from the Flow that moves the order to Ready, with Publish After Commit. The ERP subscribes through Pub/Sub API and deduplicates on EventUuid. If the ERP team later wants to publish "Order Invoiced" back into Salesforce, they publish a second platform event through the same API, and a Flow updates the order.
Scenario 2: The analytics team wants Account, Contact and Opportunity in Snowflake within minutes.
The warehouse needs every change, including ones made by data loads and other integrations, and it needs deletes.
Choice: Change Data Capture on the three objects, consumed by the warehouse's ingestion tool through Pub/Sub API. Three entities fit inside the default five. The subscriber must handle gap events by querying the record, and it needs a full resync job for overflow events and for any outage longer than three days. If the team only needs Accounts in one region, a filtered custom channel cuts the delivery count.
Scenario 3: The platform team runs on AWS and wants case events to trigger a Lambda function.
Choice: the producer is chosen first. If the Lambda reacts to "case escalated", that is a platform event. If it mirrors every case change into DynamoDB, that is CDC on Case. Either way, Event Relay delivers it to EventBridge, and an EventBridge rule invokes the Lambda. Nobody has to host or monitor a subscriber service. The relay counts as one subscribed client against the delivery allocation.
Common Mistakes
- Rebuilding CDC with a platform event. A record-triggered Flow that publishes an event containing every field of the record on every save misses changes from paths that do not run the Flow, and costs a delivery for every save. If you want record changes, use CDC.
- Using CDC to announce business events. Making a subscriber infer "deal won" from a stream of field changes puts business logic in the wrong system. Publish
Opportunity_Won__e. - Assuming events are a system of record. Retention is 72 hours for platform events and 3 days for change events. Any subscriber needs a way to catch up from the source data after a longer outage.
- Ignoring gap and overflow events. These are documented, normal events. A subscriber that only handles
CREATE,UPDATE,DELETEandUNDELETEdrifts. - Assuming Event Relay is two-way. It is outbound only. Inbound from AWS is a REST call you build and own.
- Adding subscribers without checking the allocation. Every new external client multiplies the cost of every event already being published.
Frequently Asked Questions
Q: Can a Flow subscribe to Change Data Capture events?
A: No. Flows and Process Builder processes subscribe to platform events only. To react to record changes inside Salesforce, use a record-triggered Flow, or an Apex change event trigger if the work should happen asynchronously after the transaction commits. If an external system's change needs to start a Flow, have that system publish a platform event.
Q: Does Event Relay replace MuleSoft or other middleware?
A: Only for one job: getting Salesforce events into Amazon EventBridge. It does not transform payloads, call other systems or bring events back into Salesforce. If the destination is AWS and EventBridge rules can do the routing, Event Relay removes the subscriber service you would otherwise host. If you need orchestration across several systems, you still need an integration platform.
Q: Do Apex triggers and Flows use up my event delivery allocation?
A: No. Apex triggers, Flows and Process Builder processes are excluded from the delivery count. The allocation is consumed by external clients: Pub/Sub API, CometD, empApi components in the browser, and event relays. That is why an org can publish thousands of events to internal subscribers without trouble, then hit the limit the week an external integration subscribes.
Q: Are platform events delivered in order?
A: Subscribers receive events in ReplayId order, but Salesforce only guarantees the bus preserves your intended order within a single publish call. If two events must arrive in sequence, publish them together, or include a sequence number in the payload and let the subscriber reorder.
Q: How do I get more than five objects in Change Data Capture?
A: Ask your Salesforce account representative for the Change Data Capture add-on licence. It removes the entity limit and raises the delivery allocation for Pub/Sub API and CometD clients. Before buying, check whether some of your selections could be removed, and remember that objects selected by installed AppExchange packages do not count against the five.
Key Takeaways
- Platform Events and Change Data Capture produce events; Event Relay carries them to Amazon EventBridge; Pub/Sub API is how other external clients subscribe
- Choose Platform Events when you control the message (business moments, inbound publishing, Flow subscribers), and Change Data Capture when a subscriber needs every record change
- Flows cannot subscribe to change events, and Event Relay only goes one way
- Both producers share one delivery allocation, counted per external client; Apex triggers and Flows are free
- Filtered custom channels are the largest delivery saving available
- Subscribers must deduplicate platform events on
EventUuidand handle CDC gap and overflow events - Standard volume platform events stop working on 15 December 2026; PushTopics, Generic Streaming and Outbound Messages are legacy
What's Next?
Recommended reading:
- Platform Event Delivery Limits: Measure, Attribute and Cut Usage: find out which subscriber is spending your allocation before you add another one
- Standard Volume Platform Events Retire on 15 December 2026: the two migration paths and how to phase them
- Managed Event Subscriptions for External Subscribers: keeping replay state and the stop switch inside your org
Action items:
- List every event-based integration in your org and label it Platform Event, CDC, Event Relay or legacy
- Run
SELECT COUNT_DISTINCT(SelectedEntity) FROM PlatformEventChannelMemberto see how many of your five CDC entities you are using - Check for standard volume platform events and pick a migration date before 15 December 2026
Resources & References
- Platform Events Developer Guide: publish behaviour, ordering, subscribers
- Platform Event Considerations: at-least-once delivery,
EventUuid, edition availability - Platform Event Allocations: publishing and delivery allocations by edition, and which clients count
- Change Data Capture Developer Guide: entity selection, change event structure, gap and overflow events, enrichment and filtering
- Event Relay: Salesforce Help: setup, considerations, regions and Hyperforce processing
- EventRelayConfig: Tooling API: the configuration object behind each relay
- Pub/Sub API Developer Guide: the gRPC API for publishing and subscribing, its allocations, and managed subscriptions
- Streaming Event Comparison: Salesforce's own comparison, including the legacy status of PushTopic and Generic Streaming events
- Standard Volume Platform Event Retirement (Knowledge Article 002280033): the 15 December 2026 end-of-life date and migration options
Responses
Checking your session.
Loading responses.