ERP Event-Driven Integration Comparison: Platform Events vs Event Mesh vs CDC vs Business Events
How do event-driven integration capabilities compare - Platform Events, Event Mesh, CDC, Business Events?
TL;DR
Bottom line: Every major ERP vendor now offers event-driven integration, but architectures differ fundamentally — Salesforce provides a native event bus (Platform Events + CDC), SAP offers a standalone event broker (Event Mesh / Advanced Event Mesh), Oracle uses callback-based Business Events through OIC, and Dynamics 365 routes through Dataverse. Choose based on latency needs, event volume, and cross-vendor requirements.
Key limit: Salesforce Platform Events max 1 MB payload with 3-day replay retention; SAP Event Mesh caps at 1 MB / 10 GB storage; Oracle Business Events require OIC for consumption; Dynamics 365 Data Events only support PostOperation/Async execution.
Watch out for: Delivery allocations are the hidden bottleneck — Salesforce caps event deliveries separately from publishing (delivery limits can be 1/44th of publishing limits), and SAP Event Mesh storage fills up silently if consumers lag.
Best for: Teams evaluating which ERP event-driven pattern to adopt, or architects designing cross-ERP event-driven integrations needing to understand delivery guarantees, retention, and throughput constraints.
Authentication: Each system uses its own auth — Salesforce OAuth 2.0 + Pub/Sub API (gRPC), SAP OAuth 2.0 + AMQP/MQTT/REST, Oracle OIC token-based, Dynamics 365 Dataverse via Azure AD.
System Profile
This comparison covers the event-driven integration capabilities of four major ERP platforms as of early 2026. Each vendor has a distinct architecture: Salesforce's event bus is embedded in the platform, SAP provides a separate event broker service, Oracle relies on its integration cloud for event subscription, and Microsoft routes events through Dataverse. This card does NOT cover Workday (which lacks a native event broker), NetSuite (limited to User Event SuiteScripts), or on-premise-only ERP systems.
System
Role
Event Mechanism
Protocol
Direction
Salesforce (API v62.0)
CRM/Platform — native event bus
Platform Events, CDC, Pub/Sub API
CometD, gRPC
Publish + Subscribe
SAP S/4HANA Cloud (2408)
ERP — external event broker
SAP Event Mesh / Advanced Event Mesh
AMQP 1.0, MQTT 3.1.1, REST
Publish + Subscribe
Oracle ERP Cloud (24B)
ERP — callback-based events
Business Events via OIC Adapter
SOAP callback + REST
Publish (OIC subscribes)
Dynamics 365 F&O (10.0.40+)
ERP — Dataverse-routed events
Business Events + Data Events
Dataverse SDK, Power Automate
Publish via Dataverse
API Surfaces & Capabilities
Event Mechanism
Vendor
Protocol
Best For
Max Payload
Retention
Replay?
Guaranteed Delivery?
Platform Events
Salesforce
gRPC, CometD
Custom business events, inter-app messaging
1 MB
3 days
Yes (ReplayId)
At-least-once
Change Data Capture
Salesforce
gRPC, CometD
Record-level change tracking (CRUD)
1 MB
3 days
Yes (ReplayId)
At-least-once
SAP Event Mesh
SAP
AMQP, MQTT, REST
Lightweight event-driven integration
1 MB
Queue-based (10 GB)
No
At-least-once (queue)
SAP Advanced Event Mesh
SAP (Solace)
AMQP, MQTT, REST, WebSocket
High-throughput, global event mesh
30 MB
Queue-based (6 TB)
Yes
At-least-once
Business Events
Oracle
SOAP callback via OIC
ERP module event subscriptions
Variable (callback)
OIC-managed
OIC retry
OIC retry policy
Business Events
Dynamics 365
Dataverse SDK
Finance process notifications
Dataverse record
Dataverse-managed
No native
Async retry
Data Events (CUD)
Dynamics 365
Dataverse SDK
Virtual entity change tracking
Virtual entity record
Dataverse-managed
No native
Async retry
Rate Limits & Quotas
Event Publishing Limits
System
Mechanism
Hourly Publish Limit
Daily Publish Limit
Notes
Salesforce (Enterprise)
Platform Events
~250K/hour
Up to 6.6M/day
Varies by edition; add-on licenses increase allocation
Salesforce (Enterprise)
CDC
No separate limit
Shared with Platform Events
CDC publishes automatically on record changes
SAP Event Mesh
Queue/Topic publish
No hard cap
Throughput-bound
10 GB storage cap is the effective limit
SAP Advanced Event Mesh
Queue/Topic publish
No hard cap
Throughput-bound
6 TB storage; dedicated broker instances
Oracle ERP Cloud
Business Events
No cap documented
Module-specific
Events fire on business transactions only
Dynamics 365 F&O
Business/Data Events
No cap documented
No hard daily cap
Throttled by Dataverse plug-in queue
Event Delivery / Consumption Limits
System
Mechanism
Delivery Allocation
Concurrent Subscribers
Key Constraint
Salesforce
Platform Events + CDC
~150K deliveries/day (base)
2,000 CometD clients
Delivery limit far lower than publish limit
SAP Event Mesh
Queue consumers
No per-consumer cap
Queue-count dependent
10 GB storage fills if consumers lag
SAP Advanced Event Mesh
Queue consumers
No per-consumer cap
Broker-tier dependent
6 TB storage; event replay available
Oracle ERP Cloud
OIC subscription
OIC license tier
1 OIC instance per event
OIC license determines throughput ceiling
Dynamics 365 F&O
Dataverse plug-in
Async queue capacity
Multiple per event
Async-only for virtual entities
Payload & Retention Limits
System
Max Event Payload
Retention Period
Replay Capability
Delivery Semantics
Salesforce Platform Events
1 MB
3 days
Yes (ReplayId)
At-least-once
Salesforce CDC
1 MB
3 days
Yes (ReplayId)
At-least-once
SAP Event Mesh
1 MB
Queue-based (10 GB)
No native replay
At-least-once (queue)
SAP Advanced Event Mesh
30 MB
Queue-based (6 TB)
Yes
At-least-once
Oracle Business Events
Variable (callback)
OIC-managed
OIC error hospital
At-least-once (OIC retry)
Dynamics 365 Events
Dataverse record
Dataverse-managed
No native replay
At-least-once (async retry)
Authentication
System
Event Auth Flow
Token Lifetime
Protocol Auth
Notes
Salesforce Pub/Sub API
OAuth 2.0 (JWT bearer)
Session timeout (2h default)
gRPC with OAuth bearer
Recommended for server-to-server
SAP Event Mesh
OAuth 2.0 (client credentials)
Per BTP config
AMQP SASL / MQTT auth
BTP service key provides credentials
Oracle OIC
OAuth 2.0 JWT User Assertion
Auto-refresh
Encrypted session token
Token never persisted
Dynamics 365 Dataverse
Azure AD / Entra ID
Access: 1h, Refresh: long-lived
Dataverse SDK auth
Plug-in runs in system context
Authentication Gotchas
Salesforce Pub/Sub API requires a connected app with specific event permissions — the integration user must have "Subscribe to Platform Events" permission on each event object. [src1]
SAP Event Mesh credentials are BTP service keys — rotating them requires updating all connected consumers simultaneously. [src3]
Oracle OIC: private endpoints do NOT support Business Events — you cannot use VCN private subnets for event consumption. [src5]
Dynamics 365 Dataverse plug-ins run in the system security context — field-level security is not enforced on event payloads, which can expose sensitive data. [src6]
Constraints
Salesforce Platform Events delivery allocation is separate from (and much lower than) publishing allocation — you can publish 6.6M events/day but may only deliver 150K. This is the biggest trap in Salesforce event-driven integrations.
Salesforce CDC publishes ALL record changes including batch Apex, ETL jobs, and data loads — cannot selectively suppress at publish time (use Filtered Streams at delivery instead).
SAP Event Mesh has a hard 10 GB storage ceiling — once reached, new messages are rejected until consumers drain the queues.
SAP Advanced Event Mesh is separately licensed from Event Mesh — upgrading requires a new BTP subscription and consumer re-pointing.
Oracle Business Events consumed exclusively through OIC adapters — no standalone webhook or direct API subscription. OIC license required.
Dynamics 365 Data Events only support PostOperation stage and Asynchronous execution — PreValidation, PreOperation, and Synchronous not supported for virtual entity events.
No vendor provides a native cross-vendor event mesh — integrating events between ERP systems requires a third-party broker or custom middleware.
Integration Pattern Decision Tree
START — Architect needs event-driven integration across ERP systems
├── How many ERP systems are involved?
│ ├── Single ERP → use that vendor's native event mechanism
│ │ ├── Salesforce → Platform Events (custom) or CDC (record changes)
│ │ ├── SAP S/4HANA → Event Mesh (< 10 GB) or Advanced Event Mesh
│ │ ├── Oracle ERP Cloud → Business Events via OIC
│ │ └── Dynamics 365 F&O → Business Events + Data Events
│ └── Multiple ERPs → need event broker / iPaaS
│ ├── Already have iPaaS? → MuleSoft, Boomi, Workato connectors
│ ├── Need dedicated event mesh? → SAP AEM (Solace), Kafka, Solace PubSub+
│ └── Lightweight? → Webhook relay between ERPs
├── Delivery guarantee needed?
│ ├── At-least-once (with replay) → SF Pub/Sub API, SAP AEM, Oracle OIC retry
│ ├── At-least-once (queue) → SAP Event Mesh, D365 async plug-in
│ └── Exactly-once → NOT natively supported — implement consumer idempotency
└── Event volume?
├── < 10K events/day → any vendor's native mechanism
├── 10K–100K events/day → watch SF delivery allocations; SAP EM OK
└── > 100K events/day → SAP AEM, Kafka, or Solace; SF needs add-on
Quick Reference
Capability
Salesforce
SAP S/4HANA
Oracle ERP Cloud
Dynamics 365 F&O
Notes
Native Event Mechanism
Platform Events + CDC
Event Mesh / AEM
Business Events (OIC)
Business + Data Events
All cloud-native
CDC Capability
Yes (native CDC)
Yes (via AEM Event Add-On)
Limited (OIC-based)
Yes (Data Events on virtual entities)
SF most mature
Custom Events
Yes (Platform Events)
Yes (custom topics)
Yes (Application Composer)
Yes (custom Business Events)
All support custom
Max Payload
1 MB
1 MB (EM) / 30 MB (AEM)
Variable (callback)
Dataverse record
SAP AEM most generous
Retention
3 days
Queue-based (10 GB / 6 TB)
OIC-managed
Dataverse-managed
SF clearest SLA
Replay
Yes (ReplayId)
No (EM) / Yes (AEM)
OIC error hospital
No native
SF + SAP AEM best
Protocols
gRPC, CometD
AMQP, MQTT, REST
SOAP callback
Dataverse SDK
SAP most options
Delivery Guarantee
At-least-once
At-least-once
OIC retry
Async retry
None exactly-once
Cross-Vendor Eventing
No
AEM works cross-vendor
No
No
SAP AEM only option
Pricing
Included + add-on
BTP subscription
OIC license tier
Included with F&O
SF + SAP have add-ons
Subscriber Limit
2,000 CometD clients
Broker-tier dependent
OIC instance count
Plug-in registrations
SF most restrictive
Setup Complexity
Low (declarative)
Medium (BTP config)
Medium (OIC wizard)
Medium (Visual Studio)
SF easiest
Step-by-Step Integration Guide
1. Evaluate event volume and delivery requirements
Before choosing a vendor-specific mechanism, calculate your daily event volume and required delivery guarantees. [src1]
Event Volume Assessment Checklist:
1. Count distinct event types
2. Estimate daily volume per event type
3. Sum total daily events across all types
4. Determine max acceptable delivery latency
5. Determine delivery guarantee needed
6. Check if replay/redelivery is required
7. Count number of consumers per event type
8. Calculate: total_deliveries = events * consumers_per_event
Verify: total_deliveries falls within your chosen vendor's delivery allocation.
2. Configure Salesforce Platform Events (if using Salesforce)
Create a custom Platform Event and subscribe via Pub/Sub API. [src1, src2]
# Authenticate via JWT Bearer flow
curl -X POST https://login.salesforce.com/services/oauth2/token \
-d "grant_type=urn:ietf:params:oauth:grant-type:jwt-bearer" \
-d "assertion=${JWT_TOKEN}"
# Subscribe using Pub/Sub API gRPC client
# Endpoint: api.pubsub.salesforce.com:7443
Create a service instance in BTP and subscribe to S/4HANA events. [src3, src4]
# Test consumption with REST API:
curl -X GET "https://{emhost}/messagingrest/v1/queues/{queue}/messages/consumption" \
-H "Authorization: Bearer ${ACCESS_TOKEN}" \
-H "x-qos: 1"
Verify: Check Event Mesh dashboard in BTP cockpit for message throughput
4. Configure Oracle Business Events (if using Oracle)
Subscribe to Business Events in Oracle Integration Cloud adapter. [src5]
In Oracle Integration Cloud:
1. Create a new integration flow
2. Add Oracle ERP Cloud Adapter as trigger connection
3. Select "Subscribe to Business Events" in Adapter Wizard
4. Choose the event (e.g., PO Created, Invoice Approved)
5. Configure callback service for event enrichment
Verify: Check OIC Monitoring > Integrations for event delivery status
5. Configure Dynamics 365 Data Events (if using D365)
Register a Dataverse plug-in for Finance & Operations entity events. [src6]
In Visual Studio with Power Platform Tools:
1. Create Power Platform Solution project
2. Connect to Dataverse environment linked to F&O
3. In Power Platform Explorer > Event Catalog > finance and operations
4. Right-click entity event (Created/Updated/Deleted) > Add Plugin
5. Register New Step: PostOperation, Asynchronous
6. Build and Deploy to Dataverse
Verify: Check Power Apps > Plug-in assemblies and F&O > Business Events > Active events
Code Examples
Python: Subscribe to Salesforce Platform Events via Pub/Sub API
# Input: Salesforce connected app credentials (client_id, private_key, username)
# Output: Real-time stream of Platform Event messages
import requests, jwt, time
private_key = open("server.key", "r").read()
claim = {
"iss": CLIENT_ID, "sub": USERNAME,
"aud": "https://login.salesforce.com",
"exp": int(time.time()) + 300
}
assertion = jwt.encode(claim, private_key, algorithm="RS256")
token_resp = requests.post(
"https://login.salesforce.com/services/oauth2/token",
data={"grant_type": "urn:ietf:params:oauth:grant-type:jwt-bearer",
"assertion": assertion}
)
access_token = token_resp.json()["access_token"]
# Connect to Pub/Sub API at api.pubsub.salesforce.com:7443
# Subscribe with ReplayPreset.LATEST or specific ReplayId for recovery
JavaScript/Node.js: Consume SAP Event Mesh via AMQP
# Input: OIC instance URL, integration flow ID
# Output: Integration status and event subscription details
curl -X GET "https://{oic-instance}/ic/api/integration/v1/integrations/{id}" \
-H "Authorization: Bearer ${OIC_TOKEN}" \
-H "Accept: application/json"
# Monitor recent event deliveries
curl -X GET "https://{oic-instance}/ic/api/integration/v1/monitoring/instances?status=COMPLETED&limit=10" \
-H "Authorization: Bearer ${OIC_TOKEN}"
Data Mapping
Event Payload Structure Comparison
Field Concept
Salesforce Platform Events
SAP Event Mesh
Oracle Business Events
D365 Data Events
Event type identifier
/event/EventName__e
Topic string (SAP namespace)
Business Event name (catalog)
Entity + CUD operation
Payload format
JSON (Pub/Sub API)
JSON or binary
SOAP XML callback
Dataverse entity (JSON)
Timestamp
CreatedDate (UTC)
Message timestamp (UTC)
Callback invocation time
Dataverse audit timestamp
Unique event ID
ReplayId (sequential)
Message ID (broker-assigned)
OIC correlation ID
Plug-in execution ID
Change type
Not built-in (custom field)
CloudEvents type
Event name implies action
CUD operation type
Changed fields
CDC only (ChangeEventHeader)
Not built-in
Not built-in
Full entity record
Data Type Gotchas
Salesforce CDC ChangeEventHeader.commitTimestamp is server time, not user timezone. [src2]
SAP Event Mesh uses CloudEvents format — business payload is nested in the data property. [src4]
Oracle Business Events initial notification is minimal — must call callback enrichment service for full payload. [src5]
Dynamics 365 Data Events deliver full virtual entity records including computed fields, increasing payload size. [src6]
Error Handling & Failure Points
Common Error Scenarios
Scenario
Salesforce
SAP Event Mesh
Oracle OIC
Dynamics 365
Rate/delivery limit exceeded
PLATFORM_EVENT_DELIVERY_LIMIT_EXCEEDED
Messages rejected when 10 GB full
OIC throttles per license
Async queue backlog
Consumer offline
Stored for 3-day replay
Queue until storage limit
OIC retries; fails to error hospital
Async retry; trace log
Payload too large
Publish fails: 1 MB
Rejected: 1 MB / 30 MB
Callback variable
Dataverse record limits
Auth failure
401 on Pub/Sub API
AMQP connection refused
Token refresh failure
Plug-in auth exception
Duplicate delivery
Same ReplayId received twice
Same message on nack timeout
OIC redeliver on timeout
Plug-in re-executes
Failure Points in Production
Salesforce delivery limit exhaustion: Publishing succeeds but delivery silently stops once allocation consumed. Fix: Monitor delivery usage via Setup > Platform Events > Usage; add-on license or reduce subscriber count. [src7]
SAP Event Mesh storage saturation: Offline consumer causes 10 GB fill-up; new messages rejected. Fix: Monitor queue depth; implement DLQ; upgrade to AEM (6 TB) for production. [src4]
Oracle OIC private endpoint failure: Private endpoints do NOT support Business Events — fails silently. Fix: Use public OIC endpoints for event subscriptions. [src5]
Dynamics 365 plug-in timeout: Async plug-ins have 2-minute limit; external API calls can exceed this. Fix: Offload to Azure Functions via Azure Service Bus. [src6]
Cross-vendor event ordering: Events through intermediate broker lose ordering across partitions. Fix: Same partition key for related events; saga pattern with idempotent consumers.
Anti-Patterns
Wrong: Polling for changes instead of using event-driven mechanisms
# BAD -- polling every 5 minutes wastes API calls and adds latency
while True:
changes = sf.query("SELECT Id FROM Account WHERE SystemModstamp > " + last_check)
process(changes)
time.sleep(300)
Correct: Subscribe to CDC or Platform Events
# GOOD -- CDC delivers changes in near-real-time, no wasted API calls
subscriber.subscribe("/data/AccountChangeEvent", replay_id=last_replay_id)
# Events arrive within seconds; ReplayId enables recovery
Wrong: Publishing high-volume CDC without checking delivery allocation
# BAD -- enabling CDC on 50 objects including batch-heavy ones
for obj in all_objects:
enable_cdc(obj) # 100K batch = 100K CDC events = exhausts allocation
Correct: Selective CDC enablement with Filtered Streams
# GOOD -- CDC only on critical objects; Filtered Streams for delivery control
critical_objects = ["Opportunity", "Order", "Case"]
for obj in critical_objects:
enable_cdc(obj)
Wrong: SAP Event Mesh without queue depth monitoring
// BAD -- no monitoring; consumer offline fills 10 GB; messages silently lost
receiver.on("message", (ctx) => { processEvent(ctx.message); ctx.delivery.accept(); });
Correct: Monitor queue depth and implement dead-letter queue
// GOOD -- alert on queue depth threshold; DLQ for poison messages
const stats = await getQueueStats(serviceKey, queue);
if (stats.currentSizeBytes > 8e9) alertOps("Queue near capacity");
receiver.on("message", async (ctx) => {
try { await processEvent(ctx.message); ctx.delivery.accept(); }
catch (e) { ctx.delivery.reject(); } // Routes to DLQ
});
Common Pitfalls
Confusing publishing with delivery (Salesforce): Publishing and delivering are counted separately. 1 event to 10 subscribers = 10 deliveries. Fix: Minimize subscriber count; use single fan-out subscriber. [src7]
SAP EM to AEM migration: Not an in-place upgrade — requires new BTP subscription, new broker, re-pointing all producers/consumers. Fix: Start with AEM if growth beyond 10 GB anticipated. [src3]
Oracle Business Events not firing: Must be explicitly enabled per module and profile option. Fix: Check Business Events REST API catalog; enable AP/AR/GL profile options. [src5]
D365 synchronous expectation: Virtual entity Data Events only support Async PostOperation — synchronous handlers are silently ignored. Fix: Design for eventual consistency. [src6]
No exactly-once delivery: All vendors provide at-least-once at best. Fix: Implement consumer-side idempotency using event unique IDs.
Assuming CDC is equal across vendors: Salesforce CDC captures all DML; Oracle Business Events only fire on specific transactions. Fix: Map your requirements to vendor-specific CDC scope. [src2]
Multiple consumers need the same event data independently
Only one consumer from one ERP
Direct REST API integration
Need audit trail / replay for integration recovery
Daily sync acceptable (freshness not critical)
Scheduled batch integration
Implementing saga/choreography across ERP systems
Simple point-to-point data replication
CDC replication tools (Striim, Fivetran)
Cross-System Comparison
Capability
Salesforce
SAP S/4HANA
Oracle ERP Cloud
Dynamics 365 F&O
Notes
Event Architecture
Embedded event bus
External broker (BTP)
OIC adapter callbacks
Dataverse-routed
SF most self-contained
CDC Native
Yes (CDC)
Via AEM Event Add-On
Limited (module events)
Data Events (virtual entities)
SF most comprehensive
Custom Events
Platform Events (declarative)
Custom topics (code)
Application Composer
Custom Business Events
SF easiest to create
Protocol Options
gRPC, CometD
AMQP, MQTT, REST, WebSocket
SOAP, REST (via OIC)
Dataverse SDK, Power Automate
SAP most protocols
Max Payload
1 MB
1 MB (EM) / 30 MB (AEM)
Variable
Dataverse record
SAP AEM most generous
Replay
Yes (3-day ReplayId)
No (EM) / Yes (AEM)
OIC error hospital
No native
SF clearest SLA
Event Filtering
Filtered Streams
Topic-based routing
OIC mapping
Plug-in logic
SF most declarative
Cross-Vendor
No
Yes (AEM via AMQP/MQTT)
No
No
SAP AEM only option
Delivery Guarantee
At-least-once
At-least-once
OIC retry
Async retry
None exactly-once
Setup Complexity
Low
Medium-High
Medium
Medium
SF lowest barrier
Licensing
Included + add-on
BTP + AEM license
OIC license required
Included with F&O
Oracle + SAP add-on cost
Maturity
High (since 2017)
Medium (EM 2019, AEM 2023)
Medium (since 2017)
Medium (since 2021)
SF + Oracle most mature
Important Caveats
Event-driven capabilities vary dramatically by edition and licensing — Salesforce high-volume Platform Events and SAP Advanced Event Mesh are separately licensed products.
Delivery allocations (not publishing limits) are the true bottleneck — particularly for Salesforce where delivery limits can be 1/44th of publishing limits.
No vendor provides a native cross-vendor event mesh — SAP AEM (Solace) is the closest but still requires explicit configuration for non-SAP sources.
"CDC" means different things across vendors — Salesforce CDC is field-level change streams, Oracle "Business Events" are transaction-level, Dynamics 365 "Data Events" are CUD on virtual entities.
All ERP event architectures deliver at-least-once, never exactly-once. Consumer-side idempotency is always required.
Rate limits, delivery allocations, and storage limits change with each vendor release cycle — always verify against current documentation.