I'm trying to build a high-volume integration through platform events, and I'd like to know how setResumeCheckpoint behaves when a RetryableException is thrown after the checkpoint.

According to the docs, setResumeCheckpoint starts processing events with a replay id after the last checkpoint, whereas RetryableException re-processes all events in the original trigger context (plus more). My question then is, does RetryableException reprocess only the events after the last checkpoint, or does it revert everything that has been done in a trigger.

Reference: https://developer.salesforce.com/docs/atlas.en-us.platform_events.meta/platform_events/platform_events_subscribe_compare_checkpoint_retryable.htm

2 Answers 2


I performed the following test, and found that RetryableException reverts everything committed through setResumeCheckpoint:

// Test partial commit, then error.
trigger testevent on Test_Event__e (after insert) {
    System.debug('testevent [start]: Partial Commit Test');
    System.debug('testevent [size]: ' + Trigger.new.size());
    EventBus.TriggerContext tx = EventBus.TriggerContext.currentContext();
    if (Trigger.new.size() > 1) throw new EventBus.RetryableException('Testing how retrying after a commit works.');
    System.debug('testevent [finished]');

When publishing two events at one time, this re-processes both events in subsequent instances of the trigger handler.


I've found the way to fix it. You should add another setResumeCheckpoint in the end of your method after try catch for example with replayId of the last element. Then if you will have unhandled exception like LIMIT exception it will restart your events starting from saved + 1, otherwise it will stop restarting your events firing.

  • Hey, thanks for the response. I have a couple questions on this: 1. Have you proven out that uncaught exceptions cause the replay logic to run? When I was testing, I was only able to accomplish this with (specifically) RetryableException instances explicitly thrown by my code. CPU timeout exceptions did not trigger a replay. 2. The above test models the scenario you described, where setResumeCheckpoint is set with a replay id. The test showed that this was completely ignored when an uncaught RetryableException was thrown. Do you have sample code that shows different behavior? Apr 8, 2020 at 14:59
  • Actually it works especially for Limits errors. You just should know that new trigger will starts from the next element after checkpoint. To retry trigger from resume checkpoint this checkpoint should be set before exception. Apr 9, 2020 at 15:16
  • That would be great -- Do you have sample code that shows different behavior than what I found? Apr 10, 2020 at 18:45
  • Actually it is almost the same except I added try catch between two setResumeCheckpoint. The last one is like save progress and set that it is the end, to prevent restarting trigger. Here is the sample with description developer.salesforce.com/docs/atlas.en-us.platform_events.meta/… Apr 11, 2020 at 19:23
  • So in my realization at first I add setRezumeCheckpoint with 0 element, in the end with the last one Apr 11, 2020 at 19:24

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .