[SalesForce] How to determine Platform Event Size in Apex to ensure to be within < 1 MB

The documentation on Platform event states:

The maximum event message size that you can publish is 1 MB.

Is there a native and reliable way in Apex to check whether the Platform Event I am about to publish falls within this limit?

Which parts of the event need to be considered for this check? Only field contents or also describe information about the field (i.e. is length of a custom field's api name a factor?). What is exactly considered part of the event message?

Best Answer

Maximum size allowed is 1048576 bytes (1.05MB)

When you exceed the limit, you will get below message:

(Database.Error[getFields=();getMessage=The event payload size of 1179064 bytes exceeds the maximum allowed size of 1048576 bytes;getStatusCode=PAYLOAD_SIZE_EXCEEDED;])

TESTING:
Create a platform event POC_PE__e and create 9 long text fields and use below apex method:

public static void publish() {
    String str = '1234567890', longStr = '';
    for(Integer i=0; i<100; i++) str+='1234567890';
    for(Integer i=0; i<131; i++) longStr+=str;
    longStr = longStr.left(131000);
    System.debug(poc.getBytesSize(longStr));
    POC_PE__e pe = new POC_PE__e(Long_String__c=longStr,
                                 Long_String2__c=longStr,
                                 Long_String3__c=longStr,
                                 Long_String4__c=longStr,
                                 Long_String5__c=longStr,
                                 Long_String6__c=longStr,
                                 Long_String7__c=longStr,
                                 Long_String8__c=longStr,
                                 Long_String9__c=longStr
                                );
    System.debug(JSON.serialize(pe));
    String APIs = '"attributestypePOC_PE__eLong_String__cLong_String2__cLong_String3__cLong_String4__cLong_String5__cLong_String6__cLong_String7__cLong_String8__cLong_String9__c"';
    System.debug(poc.getBytesSize(JSON.serialize(pe))-poc.getBytesSize(APIs)); //1179064 bytes
    Database.SaveResult sr = EventBus.publish(pe);
    if(sr.isSuccess()) System.debug('SUCCESS => '+sr.success);
    else System.debug('ERROR => '+sr.getErrors());
}

Long_String__c, Long_String2__c.... are event fields.

Solution:
Use this method to get string bytes size (used in example above)

public static Integer getBytesSize(String str) {
    Blob myBlob = Blob.valueof(str);
    return myBlob.size();
}

Got to this by using https://mothereff.in/byte-counter. Number of chars is same as number of bytes. Note: we get exact bytes size (1179064 bytes) shown in error message (1179064 bytes).

Conclusion: Salesforce serialises the event object(s) for transmitting to various destinations and deserialises before delivering. Only data is calculated for message size and not field API or Object API names.

Additional info:
Same is the case with lightning platform - got confirmation from salesforce support. Thats the reason you see error message on object record page when so many formula,lookup,rich text fields are included in page layout