Why CDC has all Sync Limits being an Async process

apexchange-data-capturegovernorlimits

According to Salesforce documentation.

You can add up to 50 jobs to the queue with System.enqueueJob in a single transaction. In asynchronous transactions (for example, from a batch Apex job), you can add only one job to the queue with System.enqueueJob. To check how many queueable jobs have been added in one transaction, call Limits.getQueueableJobs().

So I enabled Change Data Capture on an object Queue_Item__c.
And added this:

trigger QueueItemCDC on Queue_Item__ChangeEvent (after insert) {

    System.debug('After Insert From CDC');
    QueueItemExecutor.execute();
}

public without sharing class QueueItemExecutor {

    public static void execute() {

        System.debug(Limits.getLimitQueueableJobs());
        System.debug(Limits.getQueueableJobs());
    }

}

But the result was surprising, I got this in debug.

19:17:47.0 (1436473)|USER_DEBUG|[7]|DEBUG|After Insert From CDC
19:17:47.0 (1660299)|USER_DEBUG|[9]|DEBUG|50
19:17:47.0 (1685315)|USER_DEBUG|[10]|DEBUG|0

So the limit is showing as 50 whereas documentation says, in Async transaction the limit should be max 1.
Does anyone know why, as CDC is considered as Async why Sync limits are applied to it?

To verify I logged more Limits to check, I saw all limits are from Sync transactions .

19:33:06.0 (1938344)|USER_DEBUG|[7]|DEBUG|After Insert From CDC
19:33:06.0 (11884797)|USER_DEBUG|[9]|DEBUG|getLimitQueueableJobs 50
19:33:06.0 (11921914)|USER_DEBUG|[10]|DEBUG|getLimitFutureCalls 50
19:33:06.0 (11942764)|USER_DEBUG|[11]|DEBUG|getLimitSoslQueries 20
19:33:06.0 (11962850)|USER_DEBUG|[12]|DEBUG|getLimitQueries 100
19:33:06.0 (11981041)|USER_DEBUG|[13]|DEBUG|getLimitDmlRows 10000
19:33:06.0 (12002651)|USER_DEBUG|[14]|DEBUG|getLimitHeapSize 6000000

Best Answer

CDC events share a 1:1 relationship with transactions, so they need to have the smaller synchronous limits imposed upon them, otherwise they would likely consume too many system resources. Also remember that CDC triggers are guaranteed to run, which would be impossible to guarantee as asynchronous code only gets 250,000 executions per day, shared between Queueable, Batchable, and future methods.