ERP Event-Driven Integration Comparison: Platform Events vs Event Mesh vs CDC vs Business Events

Type: ERP Integration System: Salesforce, SAP, Oracle, Dynamics 365 Confidence: 0.87 Sources: 7 Verified: 2026-03-02 Freshness: evolving

TL;DR

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.

SystemRoleEvent MechanismProtocolDirection
Salesforce (API v62.0)CRM/Platform — native event busPlatform Events, CDC, Pub/Sub APICometD, gRPCPublish + Subscribe
SAP S/4HANA Cloud (2408)ERP — external event brokerSAP Event Mesh / Advanced Event MeshAMQP 1.0, MQTT 3.1.1, RESTPublish + Subscribe
Oracle ERP Cloud (24B)ERP — callback-based eventsBusiness Events via OIC AdapterSOAP callback + RESTPublish (OIC subscribes)
Dynamics 365 F&O (10.0.40+)ERP — Dataverse-routed eventsBusiness Events + Data EventsDataverse SDK, Power AutomatePublish via Dataverse

API Surfaces & Capabilities

Event MechanismVendorProtocolBest ForMax PayloadRetentionReplay?Guaranteed Delivery?
Platform EventsSalesforcegRPC, CometDCustom business events, inter-app messaging1 MB3 daysYes (ReplayId)At-least-once
Change Data CaptureSalesforcegRPC, CometDRecord-level change tracking (CRUD)1 MB3 daysYes (ReplayId)At-least-once
SAP Event MeshSAPAMQP, MQTT, RESTLightweight event-driven integration1 MBQueue-based (10 GB)NoAt-least-once (queue)
SAP Advanced Event MeshSAP (Solace)AMQP, MQTT, REST, WebSocketHigh-throughput, global event mesh30 MBQueue-based (6 TB)YesAt-least-once
Business EventsOracleSOAP callback via OICERP module event subscriptionsVariable (callback)OIC-managedOIC retryOIC retry policy
Business EventsDynamics 365Dataverse SDKFinance process notificationsDataverse recordDataverse-managedNo nativeAsync retry
Data Events (CUD)Dynamics 365Dataverse SDKVirtual entity change trackingVirtual entity recordDataverse-managedNo nativeAsync retry

Rate Limits & Quotas

Event Publishing Limits

SystemMechanismHourly Publish LimitDaily Publish LimitNotes
Salesforce (Enterprise)Platform Events~250K/hourUp to 6.6M/dayVaries by edition; add-on licenses increase allocation
Salesforce (Enterprise)CDCNo separate limitShared with Platform EventsCDC publishes automatically on record changes
SAP Event MeshQueue/Topic publishNo hard capThroughput-bound10 GB storage cap is the effective limit
SAP Advanced Event MeshQueue/Topic publishNo hard capThroughput-bound6 TB storage; dedicated broker instances
Oracle ERP CloudBusiness EventsNo cap documentedModule-specificEvents fire on business transactions only
Dynamics 365 F&OBusiness/Data EventsNo cap documentedNo hard daily capThrottled by Dataverse plug-in queue

Event Delivery / Consumption Limits

SystemMechanismDelivery AllocationConcurrent SubscribersKey Constraint
SalesforcePlatform Events + CDC~150K deliveries/day (base)2,000 CometD clientsDelivery limit far lower than publish limit
SAP Event MeshQueue consumersNo per-consumer capQueue-count dependent10 GB storage fills if consumers lag
SAP Advanced Event MeshQueue consumersNo per-consumer capBroker-tier dependent6 TB storage; event replay available
Oracle ERP CloudOIC subscriptionOIC license tier1 OIC instance per eventOIC license determines throughput ceiling
Dynamics 365 F&ODataverse plug-inAsync queue capacityMultiple per eventAsync-only for virtual entities

Payload & Retention Limits

SystemMax Event PayloadRetention PeriodReplay CapabilityDelivery Semantics
Salesforce Platform Events1 MB3 daysYes (ReplayId)At-least-once
Salesforce CDC1 MB3 daysYes (ReplayId)At-least-once
SAP Event Mesh1 MBQueue-based (10 GB)No native replayAt-least-once (queue)
SAP Advanced Event Mesh30 MBQueue-based (6 TB)YesAt-least-once
Oracle Business EventsVariable (callback)OIC-managedOIC error hospitalAt-least-once (OIC retry)
Dynamics 365 EventsDataverse recordDataverse-managedNo native replayAt-least-once (async retry)

Authentication

SystemEvent Auth FlowToken LifetimeProtocol AuthNotes
Salesforce Pub/Sub APIOAuth 2.0 (JWT bearer)Session timeout (2h default)gRPC with OAuth bearerRecommended for server-to-server
SAP Event MeshOAuth 2.0 (client credentials)Per BTP configAMQP SASL / MQTT authBTP service key provides credentials
Oracle OICOAuth 2.0 JWT User AssertionAuto-refreshEncrypted session tokenToken never persisted
Dynamics 365 DataverseAzure AD / Entra IDAccess: 1h, Refresh: long-livedDataverse SDK authPlug-in runs in system context

Authentication Gotchas

Constraints

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

CapabilitySalesforceSAP S/4HANAOracle ERP CloudDynamics 365 F&ONotes
Native Event MechanismPlatform Events + CDCEvent Mesh / AEMBusiness Events (OIC)Business + Data EventsAll cloud-native
CDC CapabilityYes (native CDC)Yes (via AEM Event Add-On)Limited (OIC-based)Yes (Data Events on virtual entities)SF most mature
Custom EventsYes (Platform Events)Yes (custom topics)Yes (Application Composer)Yes (custom Business Events)All support custom
Max Payload1 MB1 MB (EM) / 30 MB (AEM)Variable (callback)Dataverse recordSAP AEM most generous
Retention3 daysQueue-based (10 GB / 6 TB)OIC-managedDataverse-managedSF clearest SLA
ReplayYes (ReplayId)No (EM) / Yes (AEM)OIC error hospitalNo nativeSF + SAP AEM best
ProtocolsgRPC, CometDAMQP, MQTT, RESTSOAP callbackDataverse SDKSAP most options
Delivery GuaranteeAt-least-onceAt-least-onceOIC retryAsync retryNone exactly-once
Cross-Vendor EventingNoAEM works cross-vendorNoNoSAP AEM only option
PricingIncluded + add-onBTP subscriptionOIC license tierIncluded with F&OSF + SAP have add-ons
Subscriber Limit2,000 CometD clientsBroker-tier dependentOIC instance countPlug-in registrationsSF most restrictive
Setup ComplexityLow (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

Verify: Check event monitor in Setup > Platform Events > [Your Event] > Subscriptions

3. Configure SAP Event Mesh (if using SAP)

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:  SAP BTP service key (clientid, clientsecret, tokenendpoint, uri)
// Output: Real-time consumption of S/4HANA events

// npm install [email protected] [email protected]
const rhea = require("rhea");
const connection = rhea.connect({
  host: serviceKey.uri.replace("wss://", ""),
  port: 5671, transport: "tls",
  username: serviceKey.clientid, password: oauthToken
});
const receiver = connection.open_receiver(queueName);
receiver.on("message", (ctx) => {
  const event = JSON.parse(ctx.message.body);
  console.log("Event:", event.type, event.data);
  ctx.delivery.accept();
});

cURL: Test Oracle Business Events callback

# 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 ConceptSalesforce Platform EventsSAP Event MeshOracle Business EventsD365 Data Events
Event type identifier/event/EventName__eTopic string (SAP namespace)Business Event name (catalog)Entity + CUD operation
Payload formatJSON (Pub/Sub API)JSON or binarySOAP XML callbackDataverse entity (JSON)
TimestampCreatedDate (UTC)Message timestamp (UTC)Callback invocation timeDataverse audit timestamp
Unique event IDReplayId (sequential)Message ID (broker-assigned)OIC correlation IDPlug-in execution ID
Change typeNot built-in (custom field)CloudEvents typeEvent name implies actionCUD operation type
Changed fieldsCDC only (ChangeEventHeader)Not built-inNot built-inFull entity record

Data Type Gotchas

Error Handling & Failure Points

Common Error Scenarios

ScenarioSalesforceSAP Event MeshOracle OICDynamics 365
Rate/delivery limit exceededPLATFORM_EVENT_DELIVERY_LIMIT_EXCEEDEDMessages rejected when 10 GB fullOIC throttles per licenseAsync queue backlog
Consumer offlineStored for 3-day replayQueue until storage limitOIC retries; fails to error hospitalAsync retry; trace log
Payload too largePublish fails: 1 MBRejected: 1 MB / 30 MBCallback variableDataverse record limits
Auth failure401 on Pub/Sub APIAMQP connection refusedToken refresh failurePlug-in auth exception
Duplicate deliverySame ReplayId received twiceSame message on nack timeoutOIC redeliver on timeoutPlug-in re-executes

Failure Points in Production

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

Diagnostic Commands

# Salesforce: Check Platform Events delivery usage
curl "https://{instance}/services/data/v62.0/tooling/query?q=SELECT+Id,Name+FROM+PlatformEventUsageMetric" \
  -H "Authorization: Bearer ${SF_TOKEN}"

# SAP Event Mesh: Check queue depth and statistics
curl "https://{emhost}/messagingrest/v1/queues/{queueName}" \
  -H "Authorization: Bearer ${SAP_TOKEN}" -H "Accept: application/json"

# Oracle OIC: Check failed event deliveries
curl "https://{oic}/ic/api/integration/v1/monitoring/instances?status=FAILED&limit=20" \
  -H "Authorization: Bearer ${OIC_TOKEN}"

# Dynamics 365: Check Business Event catalog
curl "https://{org}.crm.dynamics.com/api/data/v9.2/msdyn_businesseventdefinitions" \
  -H "Authorization: Bearer ${D365_TOKEN}"

Version History & Compatibility

SystemCapabilityGA VersionStatus (2026)Key Change
SalesforcePlatform EventsWinter '17 (v38.0)GA — maturePub/Sub API (gRPC) added Summer '22
SalesforceChange Data CaptureSpring '19 (v45.0)GA — matureFiltered Streams added Winter '23
SAPEvent Mesh2019GA — basic tierComplemented by Advanced Event Mesh
SAPAdvanced Event Mesh2023GA — enterpriseEvent Studio planned early 2026
OracleBusiness Events17D (2017)GA — expandingToken-based auth added 25.02
MicrosoftBusiness Events10.0.22 (2021)GAData Events added for virtual entities
MicrosoftData Events10.0.30+ (2023)GAPostOperation/Async only

When to Use / When Not to Use

Use WhenDon't Use WhenUse Instead
Need near-real-time event notifications from ERP changesNeed bulk data migration (>100K records)business/erp-integration/erp-bulk-import-comparison/2026
Building loosely-coupled integrations surviving source downtimeNeed synchronous request-responsebusiness/erp-integration/erp-rest-api-comparison/2026
Multiple consumers need the same event data independentlyOnly one consumer from one ERPDirect REST API integration
Need audit trail / replay for integration recoveryDaily sync acceptable (freshness not critical)Scheduled batch integration
Implementing saga/choreography across ERP systemsSimple point-to-point data replicationCDC replication tools (Striim, Fivetran)

Cross-System Comparison

CapabilitySalesforceSAP S/4HANAOracle ERP CloudDynamics 365 F&ONotes
Event ArchitectureEmbedded event busExternal broker (BTP)OIC adapter callbacksDataverse-routedSF most self-contained
CDC NativeYes (CDC)Via AEM Event Add-OnLimited (module events)Data Events (virtual entities)SF most comprehensive
Custom EventsPlatform Events (declarative)Custom topics (code)Application ComposerCustom Business EventsSF easiest to create
Protocol OptionsgRPC, CometDAMQP, MQTT, REST, WebSocketSOAP, REST (via OIC)Dataverse SDK, Power AutomateSAP most protocols
Max Payload1 MB1 MB (EM) / 30 MB (AEM)VariableDataverse recordSAP AEM most generous
ReplayYes (3-day ReplayId)No (EM) / Yes (AEM)OIC error hospitalNo nativeSF clearest SLA
Event FilteringFiltered StreamsTopic-based routingOIC mappingPlug-in logicSF most declarative
Cross-VendorNoYes (AEM via AMQP/MQTT)NoNoSAP AEM only option
Delivery GuaranteeAt-least-onceAt-least-onceOIC retryAsync retryNone exactly-once
Setup ComplexityLowMedium-HighMediumMediumSF lowest barrier
LicensingIncluded + add-onBTP + AEM licenseOIC license requiredIncluded with F&OOracle + SAP add-on cost
MaturityHigh (since 2017)Medium (EM 2019, AEM 2023)Medium (since 2017)Medium (since 2021)SF + Oracle most mature

Important Caveats

Related Units