Async processing

Doing work outside the request that triggered it, with a guarantee that it eventually happens — deferred jobs, retries, and periodic work. Distinct from messaging, which is about telling other systems.

Overview

SAP SHIPSby design
Node.js →

@sap/cds Queues a service's calls, inbound messages and scheduled tasks in the cds.outbox.Messages table inside the business transaction, dispatches them after commit, retries with exponential backoff and keeps failures past maxAttempts as a dead letter queue; cds.queued() wraps a service, outboxed: true does it by configuration.

Java →

com.sap.cds:cds-services-bom Exposes CAP's transactional event queues as outbox services. The runtime ships two default outboxes, used internally for messaging and for the audit log, and custom outbox services can be registered for further isolation or scaling.

Not covered: At the table. A dead letter stays in cds.outbox.Messages for a person to revive or discard, through a query or a service the application defines; there is no console, no priority and no rate control, and Java has no callbacks yet. That is what the entries here add on top.

Licence1

LicenceSAP Developer License Agreement 3.2 CAP§ 1AlwaysA covered CAP application sends SAP product data through an external broker where it is copied, saved or processed in a non-SAP product.
  • § 1 License. Productive customer applications are limited to SAP BTP or another SAP-licensed platform, and mass extraction to a non-SAP product is restricted except where solely required for SAP interoperability.

Messaging is not automatically mass extraction, but an external broker can cross the boundary named in section 1. The data flow, volume and interoperability purpose therefore need to be checked for the concrete design.

SAP Developer License Agreement 3.2 CAP →

Artifacts8

8 of 8 artifacts
ArtifactSignals
CDS plugins4
@cap-js-community/event-queueTransactional processing of asynchronous and periodic CAP events
Signals
Functional boundary+1
@odatano/watchCAP plugin watching Cardano addresses and emitting events
Signals
Use terms
cds-event-monitoringStores, browses and resends messages a CAP service receives
Signals
Use terms
cds-natsNATS messaging service for the CAP Node.js runtime
Signals
Functional boundary+1
Packages3
@cap-js-community/sap-afc-sdkSDK for SAP Advanced Financial Closing scheduling providers on CDS
Signals
none
@sap/cdsCAP Node.js runtime
Signals
none
com.sap.cds:cds-services-bomMaven bill of materials pinning CAP Java module versions
Signals
none
Services1
Event MeshManaged queues and topics over AMQP, MQTT and REST
Signals
none

Content5

Group by
Piece, what it offers
Automate BTP Custom Domain certificates using Let's Encrypt
SAP Community, Ben, Blog
Real-Time Architecture in SAP CAP: Mastering Asynchronous Jobs, Gateways with WebSockets
SAP Community, rgadirov, BlogThe reasoningA recipe
Core changed
Quick tip: event/task scheduling in CAP Node.js (in alpha state)
SAP Community, Nico Schoenteich, Blog
Show 2 more
SAP CAP(Cloud Application Programming)开发框架概述
SAP Community, ArthurYang, Blog
SAP Job Scheduling Service + Cloud Application Programming Model application (CAP) + SAP Authorization and Trust Management Service (XSUAA)
SAP Community, former_member412792, BlogThe reasoning

Details

What changed — and what it makes stale3
@sap/cds 10.0, CAP, Node.js

The queue's runners coordinate through application-level locking: a picked-up message is marked processing and the row lock is released after selection. @sap/cds 8 did not check the status column, @sap/cds 9 held a row-level lock for the whole processing.

Makes stale:

A rolling upgrade straight from @sap/cds 8 to 10, which the guide says can double-process messages; drain the queue or upgrade through 9.

@sap/cds 9.5.1, CAP, Node.js

Before this, a tenant's outbox messages were only picked up by a background job that polled across all tenants on a fixed interval, bounding delivery latency by that poll cycle. The default processing strategy changed to trigger asynchronous, per-tenant processing as part of the request that submits the message, rather than a regular sweep over every tenant; the old polling strategy is still available by setting cds.outbox.persistent.scheduler.enabled: false.

Makes stale:

Descriptions of outbox delivery as bound by a fixed cross-tenant poll interval — since this release the default path triggers processing from the submitting request instead.

@sap/cds 7.4.0, CAP, Node.js

Before this, cds.requires.outbox: true gave an in-memory outbox — events waited in process memory until commit, then sent, with nothing surviving a crash before dispatch. The default flipped to persistent-outbox: messaging services and the audit-logging service now write to a database table before dispatch, and the old in-memory behaviour survives only as an explicit opt-out.

Makes stale:

Guidance that says enabling cds.requires.outbox gives an in-memory-only queue, or that database-backed delivery needs its own separate configuration. Since November 2023, outbox: true already means persistent-outbox.

Coverage
statecore and community, CAP
assessed
relationshipnarrow by design
also inABAP, BTP/BAIP
SourceTransactional Event Queues — capirechecked SourceTransactional Event Queues — capirechecked SourceTransactional Event Queues — capirechecked SourceTransactional Event Queues — capirechecked SourceTransactional Event Queues — capirechecked SourceTransactional Event Queues — capirechecked SourceEvent Queues in Node.js — capirechecked SourceEvents and Messaging — capirechecked SourceEvents and Messaging — capirechecked
For your agent
Ref
capability:async-processing
JSON
/capabilities/async-processing.json
MCP
Connecting an agent