Apex Sleep: what is CPU penaltySimulate/fake long running REST requestSpin locks with variable time retry backoffsApex CPU Limit ErrorTrigger Error: System.LimitException: Apex CPU time limit exceededHow can I get around Apex CPU time limit error when reassigning lead owner via Apex?Need help with the error : : Apex CPU time limit exceededCPU time out errorApex CPU time limit exceeded with big JSON objectApex CPU time limit exceeded in Apex batch classGetting CPU time errorApex Cpu Limit Exceeded Error in triggerAvoid 'Apex CPU time limit exceeded' with Batch Process
Speeding up thousands of string parses
How would an Amulet of Proof Against Detection and Location interact with the Comprehend Languages spell?
Apex Sleep: what is CPU penalty
Do the 26 richest billionaires own as much wealth as the poorest 3.8 billion people?
How did Einstein know the speed of light was constant?
Can a wizard delay learning new spells from leveling up, and instead learn different spells later?
Convenience stores in India
PhD: When to quit and move on?
What does it mean for a bass player to play "on the one"?
Explain how 'Sharing the burden' puzzle from Professor Layton and the Miracle Mask should be solved
Is it bad to suddenly introduce another element to your fantasy world a good ways into the story?
Could you sell yourself into slavery in the USA?
What's the big deal about the Nazgûl losing their horses?
Does the Milky Way orbit around anything?
Implementing absolute value function in c
Should I warn my boss I might take sick leave
In the Seventh Seal why does Death let the chess game happen?
What do you call the angle of the direction of an airplane?
Why did the "Orks" never develop better firearms than Firelances and Handcannons?
Has there ever been a cold war other than between the U.S. and the U.S.S.R.?
How can I define a very large matrix efficiently?
Term for a character that only exists to be talked to
What are the differences of checking a self-signed certificate vs ignore it?
Why is there paternal, for fatherly, fraternal, for brotherly, but no similar word for sons?
Apex Sleep: what is CPU penalty
Simulate/fake long running REST requestSpin locks with variable time retry backoffsApex CPU Limit ErrorTrigger Error: System.LimitException: Apex CPU time limit exceededHow can I get around Apex CPU time limit error when reassigning lead owner via Apex?Need help with the error : : Apex CPU time limit exceededCPU time out errorApex CPU time limit exceeded with big JSON objectApex CPU time limit exceeded in Apex batch classGetting CPU time errorApex Cpu Limit Exceeded Error in triggerAvoid 'Apex CPU time limit exceeded' with Batch Process
.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty,.everyoneloves__bot-mid-leaderboard:empty margin-bottom:0;
As we know (as of V46), there is no apex sleep method. Various workarounds have been proposed such as doing a callout to a service with platform support for sleep but this makes unit testing complicated not to mention callout-dml sequencing to consider.
Simple sleep loops such as this Util.cls method:
public static void sleep(Integer secs)
Long epochToDate = System.currentTimeMillis();
Long epochStop = epochToDate + (secs * 1000);
while (epochToDate <= epochStop)
epochToDate = System.currentTimeMillis();
run the risk of blowing up CPU limits (10 secs) for the transaction.
What is the CPU penalty of the aforementioned code sample?
apex governorlimits cpulimit
add a comment |
As we know (as of V46), there is no apex sleep method. Various workarounds have been proposed such as doing a callout to a service with platform support for sleep but this makes unit testing complicated not to mention callout-dml sequencing to consider.
Simple sleep loops such as this Util.cls method:
public static void sleep(Integer secs)
Long epochToDate = System.currentTimeMillis();
Long epochStop = epochToDate + (secs * 1000);
while (epochToDate <= epochStop)
epochToDate = System.currentTimeMillis();
run the risk of blowing up CPU limits (10 secs) for the transaction.
What is the CPU penalty of the aforementioned code sample?
apex governorlimits cpulimit
add a comment |
As we know (as of V46), there is no apex sleep method. Various workarounds have been proposed such as doing a callout to a service with platform support for sleep but this makes unit testing complicated not to mention callout-dml sequencing to consider.
Simple sleep loops such as this Util.cls method:
public static void sleep(Integer secs)
Long epochToDate = System.currentTimeMillis();
Long epochStop = epochToDate + (secs * 1000);
while (epochToDate <= epochStop)
epochToDate = System.currentTimeMillis();
run the risk of blowing up CPU limits (10 secs) for the transaction.
What is the CPU penalty of the aforementioned code sample?
apex governorlimits cpulimit
As we know (as of V46), there is no apex sleep method. Various workarounds have been proposed such as doing a callout to a service with platform support for sleep but this makes unit testing complicated not to mention callout-dml sequencing to consider.
Simple sleep loops such as this Util.cls method:
public static void sleep(Integer secs)
Long epochToDate = System.currentTimeMillis();
Long epochStop = epochToDate + (secs * 1000);
while (epochToDate <= epochStop)
epochToDate = System.currentTimeMillis();
run the risk of blowing up CPU limits (10 secs) for the transaction.
What is the CPU penalty of the aforementioned code sample?
apex governorlimits cpulimit
apex governorlimits cpulimit
edited 10 hours ago
Adrian Larson♦
114k19 gold badges128 silver badges269 bronze badges
114k19 gold badges128 silver badges269 bronze badges
asked 10 hours ago
cropredycropredy
37.8k4 gold badges45 silver badges132 bronze badges
37.8k4 gold badges45 silver badges132 bronze badges
add a comment |
add a comment |
2 Answers
2
active
oldest
votes
Some earlier experiments under versions 45 and below had suggested that CPU time was 1-5% less than elapsed time - so if you wanted to delay by 5 secs, the CPU consumed would be somewhere between 4.75 : 4.95 CPU secs
But I retried in V46 using this simple testbed:
Integer delaySecs = 15
Long start = System.currentTimeMillis();
Integer cpuStart = Limits.getCpuTime();
Util.sleep(delaySecs);
Long stop = System.currentTimeMillis();
Integer cpuStop = Limits.getCpuTime();
System.debug(LoggingLevel.INFO,'elapsed delta:' + (stop-start));
System.debug(LoggingLevel.INFO,'cpu delta:' + (cpustop-cpustart));
And got these results (V46)
delaySecs (input) elapsed (result) cpu (result)
18 18.003 10.020 (over limit)
17 17.002 9.304
16 16.003 9.265
15 15.004 8.552
14 14.017 8.001
13 13.002 7.231
...
10 10.003 5.431
...
5 5.020 2.812
4 4.002 2.298
3 3.016 1.724
2 2.016 1.146
1 1.033 0.586
YMMV and there's no guarantee that SFDC won't change the underlying implementation of System.currentTimeMillis()
to be closer 1:1 with CPU time.
How might this be useful?
- Implementing a variable backoff delay (jitter) in asynchronous queueable transactions that lock on a common resource. See this stackexchange q&a for example. Consider t concurrent queueable async transactions, all locking on the same resource. Randomly backoff by n secs ( n < 17) each transaction by sleeping, then requeueing the queueable.
By way of example, transaction 1 might back off by 3 secs, transaction 2 by 12 secs, transaction 3 by 1 sec, etc and when their backoff queueable job starts anew, they may be less likely to contend on a shared resource. Hence you have a range greater than 10 (secs) to introduce jitter delays.
You of course might need a sleep delay < 17 secs if the async transaction has already consumed a bunch of CPU before hitting some shared resource lock contention exception.
add a comment |
Why are you looking to 'sleep' and for how long? Tying up resources in a tight loop does not seem like the ideal solution.
Something that I did to get a 'job' to run at faster intervals than can be scheduled and to actually run when they are called (versus trying to use the Apex scheduler and hoping that it runs when you want it to) was to make the method a REST endpoint and then have an external program (on an external system) call the REST endpoint (via local cron) on a scheduled basis. Sure, it uses up an API call per invocation, but, because it is a synchronous REST call, Salesforce runs it immediately when you call it (and no matter how often), so it gets around the timing limitations (at least for me it does).
May not solve your use case, but just tossing the idea out there in case.
use case was multiple concurrent queueables doing aSelect for Update
on a shared resource and getting anUNABLE_TO_OBTAIN_LOCK
error; was investigating [this algo(aws.amazon.com/blogs/architecture/…) as mitigation.
– cropredy
8 hours ago
add a comment |
Your Answer
StackExchange.ready(function()
var channelOptions =
tags: "".split(" "),
id: "459"
;
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function()
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled)
StackExchange.using("snippets", function()
createEditor();
);
else
createEditor();
);
function createEditor()
StackExchange.prepareEditor(
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: false,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: null,
bindNavPrevention: true,
postfix: "",
imageUploader:
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
,
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
);
);
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fsalesforce.stackexchange.com%2fquestions%2f267966%2fapex-sleep-what-is-cpu-penalty%23new-answer', 'question_page');
);
Post as a guest
Required, but never shown
2 Answers
2
active
oldest
votes
2 Answers
2
active
oldest
votes
active
oldest
votes
active
oldest
votes
Some earlier experiments under versions 45 and below had suggested that CPU time was 1-5% less than elapsed time - so if you wanted to delay by 5 secs, the CPU consumed would be somewhere between 4.75 : 4.95 CPU secs
But I retried in V46 using this simple testbed:
Integer delaySecs = 15
Long start = System.currentTimeMillis();
Integer cpuStart = Limits.getCpuTime();
Util.sleep(delaySecs);
Long stop = System.currentTimeMillis();
Integer cpuStop = Limits.getCpuTime();
System.debug(LoggingLevel.INFO,'elapsed delta:' + (stop-start));
System.debug(LoggingLevel.INFO,'cpu delta:' + (cpustop-cpustart));
And got these results (V46)
delaySecs (input) elapsed (result) cpu (result)
18 18.003 10.020 (over limit)
17 17.002 9.304
16 16.003 9.265
15 15.004 8.552
14 14.017 8.001
13 13.002 7.231
...
10 10.003 5.431
...
5 5.020 2.812
4 4.002 2.298
3 3.016 1.724
2 2.016 1.146
1 1.033 0.586
YMMV and there's no guarantee that SFDC won't change the underlying implementation of System.currentTimeMillis()
to be closer 1:1 with CPU time.
How might this be useful?
- Implementing a variable backoff delay (jitter) in asynchronous queueable transactions that lock on a common resource. See this stackexchange q&a for example. Consider t concurrent queueable async transactions, all locking on the same resource. Randomly backoff by n secs ( n < 17) each transaction by sleeping, then requeueing the queueable.
By way of example, transaction 1 might back off by 3 secs, transaction 2 by 12 secs, transaction 3 by 1 sec, etc and when their backoff queueable job starts anew, they may be less likely to contend on a shared resource. Hence you have a range greater than 10 (secs) to introduce jitter delays.
You of course might need a sleep delay < 17 secs if the async transaction has already consumed a bunch of CPU before hitting some shared resource lock contention exception.
add a comment |
Some earlier experiments under versions 45 and below had suggested that CPU time was 1-5% less than elapsed time - so if you wanted to delay by 5 secs, the CPU consumed would be somewhere between 4.75 : 4.95 CPU secs
But I retried in V46 using this simple testbed:
Integer delaySecs = 15
Long start = System.currentTimeMillis();
Integer cpuStart = Limits.getCpuTime();
Util.sleep(delaySecs);
Long stop = System.currentTimeMillis();
Integer cpuStop = Limits.getCpuTime();
System.debug(LoggingLevel.INFO,'elapsed delta:' + (stop-start));
System.debug(LoggingLevel.INFO,'cpu delta:' + (cpustop-cpustart));
And got these results (V46)
delaySecs (input) elapsed (result) cpu (result)
18 18.003 10.020 (over limit)
17 17.002 9.304
16 16.003 9.265
15 15.004 8.552
14 14.017 8.001
13 13.002 7.231
...
10 10.003 5.431
...
5 5.020 2.812
4 4.002 2.298
3 3.016 1.724
2 2.016 1.146
1 1.033 0.586
YMMV and there's no guarantee that SFDC won't change the underlying implementation of System.currentTimeMillis()
to be closer 1:1 with CPU time.
How might this be useful?
- Implementing a variable backoff delay (jitter) in asynchronous queueable transactions that lock on a common resource. See this stackexchange q&a for example. Consider t concurrent queueable async transactions, all locking on the same resource. Randomly backoff by n secs ( n < 17) each transaction by sleeping, then requeueing the queueable.
By way of example, transaction 1 might back off by 3 secs, transaction 2 by 12 secs, transaction 3 by 1 sec, etc and when their backoff queueable job starts anew, they may be less likely to contend on a shared resource. Hence you have a range greater than 10 (secs) to introduce jitter delays.
You of course might need a sleep delay < 17 secs if the async transaction has already consumed a bunch of CPU before hitting some shared resource lock contention exception.
add a comment |
Some earlier experiments under versions 45 and below had suggested that CPU time was 1-5% less than elapsed time - so if you wanted to delay by 5 secs, the CPU consumed would be somewhere between 4.75 : 4.95 CPU secs
But I retried in V46 using this simple testbed:
Integer delaySecs = 15
Long start = System.currentTimeMillis();
Integer cpuStart = Limits.getCpuTime();
Util.sleep(delaySecs);
Long stop = System.currentTimeMillis();
Integer cpuStop = Limits.getCpuTime();
System.debug(LoggingLevel.INFO,'elapsed delta:' + (stop-start));
System.debug(LoggingLevel.INFO,'cpu delta:' + (cpustop-cpustart));
And got these results (V46)
delaySecs (input) elapsed (result) cpu (result)
18 18.003 10.020 (over limit)
17 17.002 9.304
16 16.003 9.265
15 15.004 8.552
14 14.017 8.001
13 13.002 7.231
...
10 10.003 5.431
...
5 5.020 2.812
4 4.002 2.298
3 3.016 1.724
2 2.016 1.146
1 1.033 0.586
YMMV and there's no guarantee that SFDC won't change the underlying implementation of System.currentTimeMillis()
to be closer 1:1 with CPU time.
How might this be useful?
- Implementing a variable backoff delay (jitter) in asynchronous queueable transactions that lock on a common resource. See this stackexchange q&a for example. Consider t concurrent queueable async transactions, all locking on the same resource. Randomly backoff by n secs ( n < 17) each transaction by sleeping, then requeueing the queueable.
By way of example, transaction 1 might back off by 3 secs, transaction 2 by 12 secs, transaction 3 by 1 sec, etc and when their backoff queueable job starts anew, they may be less likely to contend on a shared resource. Hence you have a range greater than 10 (secs) to introduce jitter delays.
You of course might need a sleep delay < 17 secs if the async transaction has already consumed a bunch of CPU before hitting some shared resource lock contention exception.
Some earlier experiments under versions 45 and below had suggested that CPU time was 1-5% less than elapsed time - so if you wanted to delay by 5 secs, the CPU consumed would be somewhere between 4.75 : 4.95 CPU secs
But I retried in V46 using this simple testbed:
Integer delaySecs = 15
Long start = System.currentTimeMillis();
Integer cpuStart = Limits.getCpuTime();
Util.sleep(delaySecs);
Long stop = System.currentTimeMillis();
Integer cpuStop = Limits.getCpuTime();
System.debug(LoggingLevel.INFO,'elapsed delta:' + (stop-start));
System.debug(LoggingLevel.INFO,'cpu delta:' + (cpustop-cpustart));
And got these results (V46)
delaySecs (input) elapsed (result) cpu (result)
18 18.003 10.020 (over limit)
17 17.002 9.304
16 16.003 9.265
15 15.004 8.552
14 14.017 8.001
13 13.002 7.231
...
10 10.003 5.431
...
5 5.020 2.812
4 4.002 2.298
3 3.016 1.724
2 2.016 1.146
1 1.033 0.586
YMMV and there's no guarantee that SFDC won't change the underlying implementation of System.currentTimeMillis()
to be closer 1:1 with CPU time.
How might this be useful?
- Implementing a variable backoff delay (jitter) in asynchronous queueable transactions that lock on a common resource. See this stackexchange q&a for example. Consider t concurrent queueable async transactions, all locking on the same resource. Randomly backoff by n secs ( n < 17) each transaction by sleeping, then requeueing the queueable.
By way of example, transaction 1 might back off by 3 secs, transaction 2 by 12 secs, transaction 3 by 1 sec, etc and when their backoff queueable job starts anew, they may be less likely to contend on a shared resource. Hence you have a range greater than 10 (secs) to introduce jitter delays.
You of course might need a sleep delay < 17 secs if the async transaction has already consumed a bunch of CPU before hitting some shared resource lock contention exception.
answered 10 hours ago
cropredycropredy
37.8k4 gold badges45 silver badges132 bronze badges
37.8k4 gold badges45 silver badges132 bronze badges
add a comment |
add a comment |
Why are you looking to 'sleep' and for how long? Tying up resources in a tight loop does not seem like the ideal solution.
Something that I did to get a 'job' to run at faster intervals than can be scheduled and to actually run when they are called (versus trying to use the Apex scheduler and hoping that it runs when you want it to) was to make the method a REST endpoint and then have an external program (on an external system) call the REST endpoint (via local cron) on a scheduled basis. Sure, it uses up an API call per invocation, but, because it is a synchronous REST call, Salesforce runs it immediately when you call it (and no matter how often), so it gets around the timing limitations (at least for me it does).
May not solve your use case, but just tossing the idea out there in case.
use case was multiple concurrent queueables doing aSelect for Update
on a shared resource and getting anUNABLE_TO_OBTAIN_LOCK
error; was investigating [this algo(aws.amazon.com/blogs/architecture/…) as mitigation.
– cropredy
8 hours ago
add a comment |
Why are you looking to 'sleep' and for how long? Tying up resources in a tight loop does not seem like the ideal solution.
Something that I did to get a 'job' to run at faster intervals than can be scheduled and to actually run when they are called (versus trying to use the Apex scheduler and hoping that it runs when you want it to) was to make the method a REST endpoint and then have an external program (on an external system) call the REST endpoint (via local cron) on a scheduled basis. Sure, it uses up an API call per invocation, but, because it is a synchronous REST call, Salesforce runs it immediately when you call it (and no matter how often), so it gets around the timing limitations (at least for me it does).
May not solve your use case, but just tossing the idea out there in case.
use case was multiple concurrent queueables doing aSelect for Update
on a shared resource and getting anUNABLE_TO_OBTAIN_LOCK
error; was investigating [this algo(aws.amazon.com/blogs/architecture/…) as mitigation.
– cropredy
8 hours ago
add a comment |
Why are you looking to 'sleep' and for how long? Tying up resources in a tight loop does not seem like the ideal solution.
Something that I did to get a 'job' to run at faster intervals than can be scheduled and to actually run when they are called (versus trying to use the Apex scheduler and hoping that it runs when you want it to) was to make the method a REST endpoint and then have an external program (on an external system) call the REST endpoint (via local cron) on a scheduled basis. Sure, it uses up an API call per invocation, but, because it is a synchronous REST call, Salesforce runs it immediately when you call it (and no matter how often), so it gets around the timing limitations (at least for me it does).
May not solve your use case, but just tossing the idea out there in case.
Why are you looking to 'sleep' and for how long? Tying up resources in a tight loop does not seem like the ideal solution.
Something that I did to get a 'job' to run at faster intervals than can be scheduled and to actually run when they are called (versus trying to use the Apex scheduler and hoping that it runs when you want it to) was to make the method a REST endpoint and then have an external program (on an external system) call the REST endpoint (via local cron) on a scheduled basis. Sure, it uses up an API call per invocation, but, because it is a synchronous REST call, Salesforce runs it immediately when you call it (and no matter how often), so it gets around the timing limitations (at least for me it does).
May not solve your use case, but just tossing the idea out there in case.
answered 9 hours ago
MarcDBehrMarcDBehr
3461 silver badge6 bronze badges
3461 silver badge6 bronze badges
use case was multiple concurrent queueables doing aSelect for Update
on a shared resource and getting anUNABLE_TO_OBTAIN_LOCK
error; was investigating [this algo(aws.amazon.com/blogs/architecture/…) as mitigation.
– cropredy
8 hours ago
add a comment |
use case was multiple concurrent queueables doing aSelect for Update
on a shared resource and getting anUNABLE_TO_OBTAIN_LOCK
error; was investigating [this algo(aws.amazon.com/blogs/architecture/…) as mitigation.
– cropredy
8 hours ago
use case was multiple concurrent queueables doing a
Select for Update
on a shared resource and getting an UNABLE_TO_OBTAIN_LOCK
error; was investigating [this algo(aws.amazon.com/blogs/architecture/…) as mitigation.– cropredy
8 hours ago
use case was multiple concurrent queueables doing a
Select for Update
on a shared resource and getting an UNABLE_TO_OBTAIN_LOCK
error; was investigating [this algo(aws.amazon.com/blogs/architecture/…) as mitigation.– cropredy
8 hours ago
add a comment |
Thanks for contributing an answer to Salesforce Stack Exchange!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fsalesforce.stackexchange.com%2fquestions%2f267966%2fapex-sleep-what-is-cpu-penalty%23new-answer', 'question_page');
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown