SAP Event Mesh & Advanced Event Mesh Capabilities

Type: ERP Integration System: SAP Event Mesh (Default Plan) + Advanced Event Mesh (Solace) Confidence: 0.85 Sources: 8 Verified: 2026-03-01 Freshness: 2026-03-01

TL;DR

System Profile

SAP provides three event-driven messaging services on BTP, each targeting different complexity and scale requirements. SAP Cloud Application Event Hub (Event Broker) is the entry-level option included with BTP licenses, handling up to 75 million transactions. SAP Event Mesh (formerly Enterprise Messaging) is the mid-tier offering supporting open protocols with a 1 MB message size cap. SAP Integration Suite, Advanced Event Mesh (AEM) is the enterprise-grade solution powered by Solace PubSub+ with up to 30 MB messages and on-premise support. [src3]

PropertySAP Event MeshSAP Advanced Event Mesh
VendorSAPSAP / Solace
PlatformSAP BTPSAP BTP + On-Premise + Multi-Cloud
Max Message Size1 MB10-30 MB (tier-dependent)
Max Storage10 GB25 GB - 1 TB (tier-dependent)
ProtocolsAMQP 1.0, MQTT 3.1.1, HTTP REST, WebhookAMQP 1.0, MQTT 3.1.1, JMS, REST, SMF, WebSocket
DeploymentCloud (BTP-only)Cloud, On-Premise, Hybrid
MonitoringLimitedAdvanced (event replay, tracing)
API DocsSAP Help PortalSolace Cloud Docs
StatusGAGA

API Surfaces & Capabilities

Event Mesh focuses on open web protocols over WebSocket, while AEM adds enterprise protocols (JMS, SMF) and native WebSocket support via the Solace stack. [src4, src2]

API SurfaceProtocolAvailable InBest ForReal-time?Notes
AMQP 1.0AMQP over WebSocketBoth EM + AEMEnterprise app-to-app, guaranteed deliveryYesOpen standard; queuing, routing
MQTT 3.1.1MQTT over WebSocketBoth EM + AEMIoT, low-bandwidth, edgeYesLightweight; recommended for non-cloud
HTTP RESTHTTPS/JSONBoth EM + AEMSimple publish/consumeYesStateless; no persistent connection
WebhookHTTP POSTBoth EM + AEMPush notificationsYesUse when consumer lacks AMQP/MQTT
JMSJava Message ServiceAEM onlyJava EE, legacy middlewareYesFull JMS 1.1 compliance
Solace SMFSMF over WS/TCPAEM onlyHigh-throughput, low-latencyYesProprietary; highest performance
WebSocketWS/WSSAEM onlyBrowser and real-time webYesSolace Web Messaging library

Rate Limits & Quotas

SAP Event Mesh — Default Plan Limits

Limit TypeValueNotes
Max message size1 MBAll protocols; includes headers + payload [src1]
Max storage capacity10 GBTotal across all queues [src3]
Guaranteed throughput250 KB/s (min)Guaranteed minimum [src1]
Max consumers per queue3Per connection [src1]
Max webhook unacked messages9Backpressure applied after 9 [src7]
Connections per instance50Bound by resource units [src6]

SAP Advanced Event Mesh — Service Class Limits

Limit TypeBroker 100Broker 250Broker 1KBroker 5KBroker 10KBroker 50KBroker 100K
Max message size10 MB10 MB10-30 MB30 MB30 MB30 MB30 MB
Message spool25 GB50 GB200 GB400 GB600 GB800 GB1,000 GB
Client connections1002501,0005,00010,00050,000100,000
Enterprise connections1002501,0005,00010,00030,00030,000
IoT connections1002501,0005,00010,00050,000100,000
Max queued messages240M240M240M3B3B3B3B
Queues + topic endpoints1002501,0005,00010,00050,000100,000
Transacted sessions1001001,0005,00010,00010,00010,000
Topic subscriptions500K500K500K5M5M5M5M

Note: Broker 1K supports 10 MB max message on firmware v10.25.8.3179-18 and earlier, 30 MB on v10.25.8.3179-20+. [src2]

Authentication

FlowServiceUse WhenToken LifetimeNotes
OAuth 2.0 Client CredentialsEvent MeshBTP service bindingConfigurable (12h typical)Standard BTP XSUAA binding
OAuth 2.0 Client CredentialsAEMREST API managementConfigurableSolace Cloud API token
Client Username + PasswordAEMAMQP/MQTT/SMF clientsSession-basedPer Message VPN
Client Certificate (TLS)AEMMutual TLS high-securityCertificate validityAll protocols supported

Authentication Gotchas

Constraints

Integration Pattern Decision Tree

START — Need event-driven integration in SAP landscape
|-- What scale do you need?
|   |-- Simple SAP cloud-to-cloud eventing (<10 GB, <1 MB messages)
|   |   |-- CPEA license? YES -> Event Mesh | NO (BTPEA) -> Event Hub
|   |   |-- Need webhook push? YES -> EM + webhook (max 9 unacked)
|   |   '-- No webhook? -> EM with AMQP/MQTT consumer
|   |-- Enterprise-grade (>1 MB, >10 GB, or >50 connections)
|   |   |-- Messages > 1 MB? -> Advanced Event Mesh
|   |   |-- Need on-prem broker? -> Advanced Event Mesh (only option)
|   |   '-- Need event replay? -> Advanced Event Mesh
|   '-- IoT / high-volume (>10K connections)
|       '-- Advanced Event Mesh Broker 10K or higher
|-- Which protocol?
|   |-- AMQP 1.0 -> Both EM and AEM
|   |-- MQTT 3.1.1 -> Both EM and AEM
|   |-- HTTP REST -> Both EM and AEM
|   |-- JMS -> AEM only
|   '-- SMF -> AEM only (highest throughput)
'-- S/4HANA business events?
    |-- Notification (no payload) -> Standard, EM or AEM
    |-- Full-state (with payload) -> Need Event Add-On for ERP
    '-- Custom events -> RAP business events or CAP-based

Quick Reference

CapabilityEvent Mesh (Default)AEM (Broker 1K)AEM (Broker 100K)
Max message size1 MB10-30 MB30 MB
Storage10 GB200 GB1,000 GB
Connections50/instance1,000100,000
ProtocolsAMQP, MQTT, REST, WebhookAMQP, MQTT, JMS, REST, SMF, WSAMQP, MQTT, JMS, REST, SMF, WS
DeploymentBTP cloud onlyCloud + On-Prem + HybridCloud + On-Prem + Hybrid
Event replayNoYesYes
Dynamic Message RoutingNoYesYes
Queue depthLimited by 10 GB240M messages3B messages
Topic subscriptionsLimited by RU500K5M
MonitoringBasic BTP cockpitSolace Event PortalSolace Event Portal
Setup complexityLowMediumMedium-High
CostLow (CPEA credits)MediumHigh

Step-by-Step Integration Guide

1. Create an Event Mesh Service Instance on BTP

Create a service instance in the BTP Cockpit or via the CF CLI. [src5]

# Create service instance via CF CLI
cf create-service enterprise-messaging default my-event-mesh \
  -c '{"emname":"my-event-mesh","namespace":"sap/btp/myapp","version":"1.1.0","options":{"management":true,"messagingrest":true,"messaging":true}}'

# Create a service key for credentials
cf create-service-key my-event-mesh my-key
cf service-key my-event-mesh my-key

Verify: cf service my-event-mesh -> expected: status: create succeeded

2. Obtain OAuth Token and Publish a Message (REST)

Use the service key credentials to obtain an OAuth token, then publish. [src4, src5]

# Get OAuth token
TOKEN=$(curl -s -X POST "$TOKEN_URL" \
  -H "Content-Type: application/x-www-form-urlencoded" \
  -d "grant_type=client_credentials&client_id=$CLIENT_ID&client_secret=$CLIENT_SECRET" \
  | jq -r '.access_token')

# Publish a message to a topic
curl -X POST "$REST_URL/messagingrest/v1/topics/sap%2Fbtp%2Fmyapp%2Forders%2Fcreated" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -H "x-qos: 1" \
  -d '{"orderId":"ORD-001","status":"created"}'

Verify: HTTP response 204 No Content -> message published

3. Create a Queue and Subscribe to Topics

Create a queue that subscribes to topic patterns. [src5, src7]

# Create a queue
curl -X PUT "$REST_URL/messagingrest/v1/queues/order-processor" \
  -H "Authorization: Bearer $TOKEN"

# Subscribe queue to a topic pattern
curl -X PUT "$REST_URL/messagingrest/v1/queues/order-processor/subscriptions/sap%2Fbtp%2Fmyapp%2Forders%2F%2A" \
  -H "Authorization: Bearer $TOKEN"

Verify: curl "$REST_URL/messagingrest/v1/queues/order-processor" -> queue details with subscription count

4. Consume Messages from Queue

Pull messages from the queue using REST or connect with AMQP/MQTT for push-based consumption. [src4]

# Consume one message (REST pull)
curl -X POST "$REST_URL/messagingrest/v1/queues/order-processor/messages/consumption" \
  -H "Authorization: Bearer $TOKEN" \
  -H "x-qos: 1"

# Acknowledge the message
curl -X POST "$REST_URL/messagingrest/v1/queues/order-processor/messages/acknowledgement" \
  -H "Authorization: Bearer $TOKEN" \
  -H "x-qos: 1" \
  -H "x-message-id: <message-id-from-response>"

Verify: Queue depth decreases by 1 after acknowledgment

Code Examples

Python: Publish and Consume via AMQP 1.0

# Input:  Service key credentials (AMQP endpoint, OAuth token)
# Output: Published message + consumed message from queue

import requests
from proton import Message
from proton.handlers import MessagingHandler
from proton.reactor import Container

def get_token(token_url, client_id, client_secret):
    resp = requests.post(token_url, data={
        "grant_type": "client_credentials",
        "client_id": client_id,
        "client_secret": client_secret
    })
    resp.raise_for_status()
    return resp.json()["access_token"]

class Publisher(MessagingHandler):
    def __init__(self, url, address, token):
        super().__init__()
        self.url = url
        self.address = address
        self.token = token

    def on_start(self, event):
        conn = event.container.connect(
            self.url, user="$consumer",
            password=self.token, sasl_enabled=True)
        event.container.create_sender(conn, self.address)

    def on_sendable(self, event):
        msg = Message(body='{"orderId":"ORD-002"}')
        msg.content_type = "application/json"
        event.sender.send(msg)
        event.sender.close()
        event.connection.close()

JavaScript/Node.js: Consume via MQTT 3.1.1

// Input:  Service key with MQTT endpoint + OAuth token
// Output: Real-time event consumption via MQTT

const mqtt = require("mqtt"); // [email protected]
const client = mqtt.connect(MQTT_URL, {
  username: "$consumer",
  password: TOKEN,
  protocolVersion: 4, // MQTT 3.1.1
  clean: true,
});

client.on("connect", () => {
  client.subscribe("sap/btp/myapp/orders/+", { qos: 1 });
});

client.on("message", (topic, message) => {
  console.log(`Topic: ${topic}, Payload: ${message.toString()}`);
});

cURL: Quick Test — Publish and Check Queue

# Get token
TOKEN=$(curl -s -X POST "$TOKEN_URL" \
  -d "grant_type=client_credentials&client_id=$CLIENT_ID&client_secret=$CLIENT_SECRET" \
  | jq -r '.access_token')

# Publish test message
curl -v -X POST "$REST_URL/messagingrest/v1/topics/sap%2Fbtp%2Fmyapp%2Ftest" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"test":true}'
# Expected: 204 No Content

# Check queue depth
curl -s "$REST_URL/messagingrest/v1/queues/my-queue" \
  -H "Authorization: Bearer $TOKEN" | jq '.queueDepth'

Data Mapping

S/4HANA Business Events to Event Mesh

S/4HANA ObjectEvent TypeTopic PatternPayloadNotes
Business PartnerCreated/Changed/Deletedsap/s4/beh/businesspartner/v1/BusinessPartner/Created/v1Notification (key only)Full-state requires Event Add-On
Sales OrderCreatedsap/s4/beh/salesorder/v1/SalesOrder/Created/v1NotificationCloudEvents format
Purchase OrderChangedsap/s4/beh/purchaseorder/v1/PurchaseOrder/Changed/v1NotificationKey fields in data
Material DocumentPostedsap/s4/beh/materialdocument/v1/MaterialDocument/Posted/v1NotificationGoods receipt/issue

Data Type Gotchas

Error Handling & Failure Points

Common Error Codes

CodeMeaningCauseResolution
401UnauthorizedToken expired or invalidRe-authenticate; implement token refresh before expiry
403ForbiddenNamespace permission deniedCheck service key namespace scope
413Payload Too LargeMessage exceeds 1 MB (EM) or tier limit (AEM)Reduce payload; use reference pattern; upgrade to AEM
429Too Many RequestsThroughput or connection limit exceededExponential backoff; upgrade tier; distribute load
503Service UnavailableMaintenance or capacity issueRetry with backoff; circuit breaker pattern

Failure Points in Production

Anti-Patterns

Wrong: Sending full business objects as event payloads

# BAD — Sends entire 500 KB sales order; hits 1 MB limit
event = {"type": "SalesOrderCreated", "data": get_full_sales_order(order_id)}

Correct: Send notification with key, fetch on demand

# GOOD — Lightweight notification; consumer fetches full object via OData
event = {"type": "SalesOrderCreated", "data": {"SalesOrder": order_id}}

Wrong: REST polling for real-time consumption

// BAD — Polling every 100ms wastes throughput quota
setInterval(async () => {
  const msg = await fetch(`${REST_URL}/queues/myqueue/messages/consumption`);
}, 100);

Correct: AMQP or MQTT push consumption

// GOOD — Persistent connection, push delivery, proper QoS
client.subscribe("sap/btp/myapp/orders/+", { qos: 1 });
client.on("message", (topic, msg) => processMessage(JSON.parse(msg)));

Wrong: Single catch-all queue for all events

# BAD — No filtering, slow consumers block everything
queue: "catch-all" -> subscription: "sap/btp/myapp/#"

Correct: Dedicated queues per concern

# GOOD — Independent scaling, failure isolation
queue: "order-processor"   -> subscription: "sap/btp/myapp/orders/*"
queue: "invoice-generator" -> subscription: "sap/btp/myapp/invoices/*"
queue: "audit-logger"      -> subscription: "sap/btp/myapp/+/+/+"

Common Pitfalls

Diagnostic Commands

# Check Event Mesh service instance status
cf service my-event-mesh

# List all queues and their depth
curl -s "$REST_URL/messagingrest/v1/queues" \
  -H "Authorization: Bearer $TOKEN" | jq '.[]|{name,queueDepth,consumers}'

# Check specific queue details
curl -s "$REST_URL/messagingrest/v1/queues/order-processor" \
  -H "Authorization: Bearer $TOKEN" | jq '.'

# List topic subscriptions for a queue
curl -s "$REST_URL/messagingrest/v1/queues/order-processor/subscriptions" \
  -H "Authorization: Bearer $TOKEN" | jq '.[]'

# Test publish (should return 204)
curl -v -X POST "$REST_URL/messagingrest/v1/topics/sap%2Fbtp%2Fmyapp%2Fhealth" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"ping":true}'

# Check OAuth token validity
curl -s "$TOKEN_URL/tokeninfo" \
  -H "Authorization: Bearer $TOKEN" | jq '.expires_in'

Version History & Compatibility

Version / MilestoneDateStatusKey Changes
Enterprise Messaging (original)2018RebrandedOriginal name before SAP Event Mesh
SAP Event Mesh Default Plan2020GAAMQP 1.0, MQTT 3.1.1, REST support
SAP Integration Suite, AEM2022GASolace PubSub+; 7 service classes; JMS/SMF/WS
SAP Cloud Application Event Hub2024GABasic tier included with BTP license; 75M tx
AEM Broker 1K firmware update2024UpdateMax message size 10 MB -> 30 MB on newer firmware
Event Mesh CPEA-only2024CurrentNot available standalone under BTPEA

When to Use / When Not to Use

Use WhenDon't Use WhenUse Instead
Simple S/4HANA-to-BTP events, <1 MB, <50 connectionsMessages > 1 MB or need on-prem brokerAdvanced Event Mesh (Broker 1K+)
Lightweight pub/sub between BTP microservicesNeed JMS for Java EE middlewareAdvanced Event Mesh (JMS)
Small team, <10 queues, CPEA licenseNeed event replay or advanced monitoringAdvanced Event Mesh (Event Portal)
IoT edge-to-cloud with <250 MQTT devices>250 IoT connections or need SMFAdvanced Event Mesh (Broker 250+)
Cross-cloud mesh, multi-region deploymentOnly basic cloud-to-cloud in single regionEvent Mesh (simpler, lower cost)
Enterprise with >1,000 concurrent connectionsBudget pilot with <50 connectionsEvent Mesh Default Plan

Cross-System Comparison

CapabilitySAP Event MeshSAP Advanced Event MeshSAP Cloud Application Event Hub
Max message size1 MB10-30 MBNot published
Max storage10 GB25 GB - 1 TBN/A (transaction-based)
ProtocolsAMQP, MQTT, REST, WebhookAMQP, MQTT, JMS, REST, SMF, WSHTTP (SAP-native)
Max connections50/instance100-100,000N/A
On-prem supportNoYesNo
Event replayNoYesNo
Multi-cloud meshNoYes (DMR)No
MonitoringBasicSolace Event PortalBasic
S/4HANA integrationNativeNative + Event Add-OnNative (limited)
LicensingCPEACPEA or subscriptionIncluded with BTP
Setup complexityLowMedium-HighMinimal
Max transactionsUsage-basedTier-based75M included

Important Caveats

Related Units