Do Alarms really have a 1min. cooldown?

862 views
Skip to first unread message

Juraj M.

unread,
Apr 16, 2022, 4:53:56 PM4/16/22
to Chromium Extensions
The docs says alarms won't fire in less than 1 min:

However, if I open a console in my published extension and run this:
```
browser.alarms.onAlarm.addListener(console.warn);
browser.alarms.create({when: Date.now() + 1000});
```
It's gonna print console after 1 second. And if I run it again, it will run it again with no cooldown. It works also in Firefox.

Can I count on this working? And can I count on `browser.alarms.create({when: Date.now()})` to run it right away?

Cuyler Stuwe

unread,
Apr 16, 2022, 5:02:47 PM4/16/22
to Juraj M., Chromium Extensions
The 1 minute timeout only applies to deployed extensions, not sideloaded ones.

It’s a little misleading and confusing, for sure.

--
You received this message because you are subscribed to the Google Groups "Chromium Extensions" group.
To unsubscribe from this group and stop receiving emails from it, send an email to chromium-extens...@chromium.org.
To view this discussion on the web visit https://groups.google.com/a/chromium.org/d/msgid/chromium-extensions/bfe77491-e582-4dd1-8dc1-4495eda028den%40chromium.org.

Juraj M.

unread,
Apr 16, 2022, 5:06:07 PM4/16/22
to Chromium Extensions, salem...@gmail.com, Chromium Extensions, Juraj M.
I said in the "published extension" which means "deployed" :).
You can try it yourself, open any extension page, open console and schedule alarm. It works for me.

wOxxOm

unread,
Apr 16, 2022, 5:06:35 PM4/16/22
to Chromium Extensions, salem...@gmail.com, Chromium Extensions, juraj....@gmail.com
It means one alarm per minute, so it won't delay the alarm that wasn't preceded by an earlier alarm within the last minute.

Juraj M.

unread,
Apr 16, 2022, 5:20:40 PM4/16/22
to Chromium Extensions, wOxxOm, salem...@gmail.com, Chromium Extensions, Juraj M.
Thanks wOxxOm! That sounds insanely complicated!
So if I understand this correctly, using `Date.now()` will always work - run the alarm right away, but anything higher may get delayed by 1 minute, if there is another alarm scheduled before. Right?

Cuyler Stuwe

unread,
Apr 16, 2022, 5:22:38 PM4/16/22
to wOxxOm, Chromium Extensions, juraj....@gmail.com
Also, in principle, running things in the console often just works differently from code running on the page.

wOxxOm

unread,
Apr 16, 2022, 5:43:01 PM4/16/22
to Chromium Extensions, juraj....@gmail.com, wOxxOm, salem...@gmail.com, Chromium Extensions
>  using `Date.now()` will always work

No. If we invert the note in the documentation, the alarm will run immediately only in case the last triggered alarm was more than 1 minute ago.

Juraj M.

unread,
Apr 17, 2022, 3:44:32 AM4/17/22
to Chromium Extensions, wOxxOm, Juraj M., salem...@gmail.com, Chromium Extensions
wOxxOm , that doesn't match the real world example.
Let's make a simple experiment.
Let's create a bunch of alarms with 2 second interval between them and then execute this in a development and prod. environment (on an extension page, not a service worker).
```
await (async () => {
const timeout = seconds => new Promise(resolve => setTimeout(resolve, seconds * 1000));
browser.alarms.onAlarm.addListener(console.warn);

browser.alarms.create('test_a', {when: Date.now()});
await timeout(2);
browser.alarms.create('test_b', {when: Date.now()});
await timeout(2);
browser.alarms.create('test_a', {when: Date.now()});
await timeout(2);
browser.alarms.create('test_x', {when: Date.now() + 5000});
await timeout(2);
browser.alarms.create('test_y', {when: Date.now() + 5000});
await timeout(2);
browser.alarms.create('test_a', {when: Date.now()});
})();
```
When running in DEV mode, this is the result:
```
09:22:47.640 {name: 'test_a', scheduledTime: 1650180167640}
09:22:49.641 {name: 'test_b', scheduledTime: 1650180169640}
09:22:51.642 {name: 'test_a', scheduledTime: 1650180171642}
09:22:57.649 undefined
09:22:57.647 {name: 'test_a', scheduledTime: 1650180177646}
09:22:58.647 {name: 'test_x', scheduledTime: 1650180178643}
09:23:00.646 {name: 'test_y', scheduledTime: 1650180180645}
```
As you would expect, everything is running right away, including X and Y alarms which were delayed by 5 and 5 + 2 seconds. The "undefined" is the result of the awaited promise.

Running the same code on the released extension:
```
09:21:37.802 {name: 'test_a', scheduledTime: 1650180097800}
09:21:39.802 {name: 'test_b', scheduledTime: 1650180099801}
09:21:41.803 {name: 'test_a', scheduledTime: 1650180101803}
09:21:47.808 undefined
09:21:47.810 {name: 'test_a', scheduledTime: 1650180107806}
09:22:47.812 {name: 'test_y', scheduledTime: 1650180110805}
09:22:47.813 {name: 'test_x', scheduledTime: 1650180108804}
```
As you would NOT expect, all alarms scheduled with Date.now() were executed on time (!) and only those X and Y which were scheduled to the future were actually delayed by 1 minute.
And as a bonus, running this in Firefox gives same results in DEV/PROD - no delays at all.

Maybe this is the case of "past alarms" which will run right away?
I have to say, I'm very confused about this behaviour and what the docs says :(
Can you help me make a sense of this? I doubt this is related to the fact that I run it in console.

wOxxOm

unread,
Apr 17, 2022, 4:06:19 AM4/17/22
to Chromium Extensions, juraj....@gmail.com, wOxxOm, salem...@gmail.com, Chromium Extensions
AFAICT per the source code of Chromium's implementation of this API, calling create() will forcibly run the polling loop at the time of this created alarm if it occurs sooner than the next normal polling cycle. Since the loop will run after the alarm's time is already in the past, it'll trigger onAlarm event. So, evidently, create() with `when` is exempted from the restriction. This may be intentional or an oversight of the API implementation.

Juraj M.

unread,
Apr 17, 2022, 4:36:48 AM4/17/22
to Chromium Extensions, wOxxOm, Juraj M., salem...@gmail.com, Chromium Extensions
Thanks wOxxOm!
You're the best!
Happy holiday :)

Robbi

unread,
Apr 17, 2022, 12:01:21 PM4/17/22
to Chromium Extensions, juraj....@gmail.com, wOxxOm, salem...@gmail.com, Chromium Extensions
I did some tests and I can confirm what @wOxxOm wrote ("calling create () will forcibly run the polling loop at the time of this created alarm")
This behavior might be acceptable,
however, when the onAlarm event trigger, the delayed alarms should be honored before the current event
Even better if they followed the right order based on the "sceduledTime" property.
Doesn't that seem reasonable to you?
Also because an alarm could modify some state variables and therefore invalidate the logic of the extension itself.

With this snippet, adapted from the @juraj one, is possible to verify that the event associated with the 'long' alarm trigger at the same time as the 'short' alarm,
but in practice the code referring to 'short' precedes that of 'long'.

(_ => {
    function alarmHandler(a) {
        var d1 = new Date(a.scheduledTime);
        console.log('\nprogr: ' + ++idx[a.name] + '\talarm_name: ' + a.name + '\tscheduled at ' + d1.getHours() + ':' + ('' + d1.getMinutes()).padStart(2, '0') + ':' + ('' + d1.getSeconds()).padStart(2, '0'));
        var d2 = Date.now();
        console.log('The alarm is ' + (d2 - d1) + 'ms late.')
        /* chrome.alarms.getAll(b =>  console.table(b) ) */
    }
    var idx = {short: 0, long: 0};
    chrome.alarms.onAlarm.removeListener(alarmHandler);
    chrome.alarms.onAlarm.addListener(alarmHandler);
    chrome.alarms.clearAll(async _ =>  {
        var d = new Date();
        console.log('Now is: ' + d.getHours() + ':' + ('' + d.getMinutes()).padStart(2, '0') + ':' + ('' + d.getSeconds()).padStart(2, '0'));

        await chrome.alarms.create('long', {when: Date.now() + 180 * 1000, periodInMinutes: 3});
        await chrome.alarms.create('short', {when: Date.now() + 30 * 1000, periodInMinutes: 1});

        chrome.alarms.getAll(a =>  {
            a.forEach(v => {
                var d = new Date(v.scheduledTime);
                console.log('Alarm_name: ' + v.name + '\tScheduled at: ' + d.getHours() + ':' + ('' + d.getMinutes()).padStart(2, '0') + ':' + ('' + d.getSeconds()).padStart(2, '0'))
            })
        })
    })
})()

Jackie Han

unread,
Apr 18, 2022, 9:44:24 AM4/18/22
to Juraj M., Chromium Extensions, wOxxOm, salem...@gmail.com
In my test, in devtools console, in an extension page of a released extension, an alarm created by `when` has two behaviors.

// for debug
chrome.alarms.onAlarm.addListener(console.warn);

Behavior 1: the alarm event fires as soon as possible, as `when` specified, less than 1 minute.
chrome.alarms.create("test", {when: Date.now() + 2000});
// the result shows after 2 seconds
// you can repeat it after seeing the last result.

Behavior 2: the alarm event is delayed, not as `when` specified, and needs to wait 1 minute.
chrome.alarms.create("test", {when: Date.now() + 2000});
// wait 1 second manually (less than 2 seconds) and exec it again
chrome.alarms.create("test", {when: Date.now() + 2000}); 
// the result shows after 1 minute

My "guess" about these two behaviors is:
As a special case, if we've never checked for an alarm before (e.g. during startup), let alarms fire asap. 
In behavior 1, the alarm "test" is newly created, so Chrome schedules it asap.
In behavior 2, the alarm "test" is newly created and scheduled asap, but it is replaced by the same name alarm quickly and scheduled again, now Chrome thinks this alarm is checked and waits for the min_granularity.


Jackie Han

unread,
Apr 18, 2022, 10:27:49 AM4/18/22
to Juraj M., Chromium Extensions, wOxxOm, salem...@gmail.com
Additional tests for two different named alarms:

Test-A:
chrome.alarms.create("test1", {when: Date.now() + 4000});
// wait 1 second
chrome.alarms.create("test2", {when: Date.now() + 4000});
// show test1 result after 4 seconds.
// test2 needs to wait 1 minute

Test-B:
chrome.alarms.create("test1", {when: Date.now() + 4000});
// wait 1 second
chrome.alarms.create("test2", {when: Date.now() + 4000});
// show test1 result after 4 seconds.
// create test1 again after seeing test1 result
chrome.alarms.create("test1", {when: Date.now() + 4000});
// show both test1 and test2 result after 4 seconds, don't need to wait 1 minute for test2

I think these behaviors depend on the implementation details.
About the original question("Can I count on this working?"), it's risky!

Robbi

unread,
Apr 18, 2022, 11:13:08 AM4/18/22
to Chromium Extensions, Jackie Han, Chromium Extensions, wOxxOm, salem...@gmail.com, juraj....@gmail.com
Hi Jackie Han,
about my test with 2 different named alarms, I notice that when both alarms triggers
the chronological order of "scheduledTime" is not respected ( which doesn't seem very nice thing to me )
If you have the patience to launch my snippet and wait 4 minutes you can check it.
This is the log output:

Now is: 17:06:02
Alarm_name: long    Scheduled at: 17:10:03
Alarm_name: short    Scheduled at: 17:07:33

progr: 1    alarm_name: short    scheduled at 17:07:33
The alarm is 7ms late.

progr: 2    alarm_name: short    scheduled at 17:08:33
The alarm is 38ms late.

progr: 3    alarm_name: short    scheduled at 17:09:33
The alarm is 1205ms late.
------------------------------------------------------------------------------------------
progr: 4    alarm_name: short    scheduled at 17:10:33
The alarm is 1230ms late.

progr: 1    alarm_name: long    scheduled at 17:10:03
The alarm is 31232ms late.

Jackie Han

unread,
Apr 18, 2022, 11:50:15 AM4/18/22
to Robbi, Chromium Extensions, wOxxOm, salem...@gmail.com, juraj....@gmail.com
Hi Robbi,

The original question focuses on behaviors of `when` only alarms, so my tests are `when` only too.

For `when + periodInMinutes` alarms, they are delayed definitely if there are other alarms(especially `periodInMinutes` is 1). The order of events is not guaranteed (no documents say that, and it is not a problem usually).

Robbi

unread,
Apr 18, 2022, 12:30:31 PM4/18/22
to Chromium Extensions, Jackie Han, Chromium Extensions, wOxxOm, salem...@gmail.com, juraj....@gmail.com, Robbi
I have never read about particular behaviors when using periodInMinutes or delayInMinutes.
Never even heard that these kind of alarms are honored with a lower or higher priority than an alarm scheduled with the "when" clause.
In any case the snippet can be rewritten by setting a new "when" for the alarms inside the event handler.
The result, which I have just tested, obviously does not change.
That this is not usually a problem I think is just a subjective opinion that I do not agree with.
We both know very well that alarms API is not a Swiss watch;however, I believe that an effort can be made to ensure certain minimum standards
On the other hand, if this is a intentional or desired behavior, I would be happy to be explained why or that some documentation is provided that resolves doubts (not just mine).

Cuyler Stuwe

unread,
Apr 18, 2022, 12:42:23 PM4/18/22
to Robbi, Chromium Extensions, Jackie Han, juraj....@gmail.com, wOxxOm
Another aspect of this to consider is the human aspect, especially with regard to the fact that the browser APIs can be volatile.

Put simply: If you find a way to schedule alarms more often than once per minute in the current version of Chrome, Google is likely to say “Welp, we didn’t mean to let you do that” in a future version and patch it up.

It’s important to recognize that Chrome’s auto-update behavior means that it’s essentially SaaS. The things you can and can’t do in it today can always change.

Cuyler Stuwe

unread,
Apr 18, 2022, 12:47:24 PM4/18/22
to Cuyler Stuwe, Chromium Extensions, Jackie Han, Robbi, juraj....@gmail.com, wOxxOm
The median tenure of a Googler is 1.1 years, so you would expect to wait at minimum 1-2 years for new devs to replace the ones responsible for the current system.

New devs will show up and think the current system is absolute trash (as new devs on every codebase in existence throughout all history tend to do) and then the API will probably revert into something more abandonware/maintenance mode. That’ll keep things stable for a while, until someone who is bored decides to change things for change’s sake (e.g., MV3).

Cuyler Stuwe

unread,
Apr 18, 2022, 12:51:24 PM4/18/22
to Cuyler Stuwe, Chromium Extensions, Jackie Han, Robbi, juraj....@gmail.com, wOxxOm
And to add to my last message, in case the point wasn’t implicitly obvious:

That period where there’s a lull in interest (e.g., the mid-2010s for MV2) is when you can reasonably expect little “tricks” like what you’re trying to do here to work reliably without being patched for an extended period.

Jackie Han

unread,
Apr 18, 2022, 2:10:11 PM4/18/22
to Robbi, Chromium Extensions, wOxxOm, salem...@gmail.com, juraj....@gmail.com
I have never read about particular behaviors when using periodInMinutes or delayInMinutes. 
Never even heard that these kind of alarms are honored with a lower or higher priority than an alarm scheduled with the "when" clause.

"delayInMinutes" means that you can't specify a value that is less than one minute, so it is not related to the original topic.
"periodInMinutes" means it will be repeated forever(e.g. 48 times per day in 5 years) until you clear it. I don't expect it is no delay or very accurate. I have an extension that uses `when` and `periodInMinutes: 1`, it always delays over 30 seconds.

In any case the snippet can be rewritten by setting a new "when" for the alarms inside the event handler.
Yes, they are similar, but maybe have a little difference like setTimeout vs setInterval.

In short, the behavior of alarm api depends on the specific implementation. The document only says "Chrome limits alarms to at most once every 1 minute but may delay them an arbitrary amount more". So any trick is risky, as my previous tests proved that the `when` trick is not always reliable.

In my opinion, if many developers need a more precise api (the delay is very small, not over a few seconds) or need to schedule less than one minute, we should file a feature request (new api or support new behavior). I remember I already filed one.

Robbi

unread,
Apr 18, 2022, 2:32:33 PM4/18/22
to Chromium Extensions, Jackie Han, Chromium Extensions, wOxxOm, salem...@gmail.com, juraj....@gmail.com, Robbi
Perhaps I have not made myself clear; I'm not asking for a Swiss watch, I'm okay with the event doesn't trigger more than once a minute and I've never tried in any way to hack this behavior.
However, I would like the chronological order of "scheduledTime" to be respected when 2 or more alarms are triggered.
I had not realized until now that there was no implicit rule that imposed an order.
It would seem to me a "good thing" to know how to predict the ORDER of the code flow a priori.
However, repeating my test at different times (but always with the same criteria) I found that the order of "scheduledTime" is SOMETIMES respected (that's mysterious)

Jackie Han

unread,
Apr 18, 2022, 11:42:24 PM4/18/22
to Robbi, Chromium Extensions, wOxxOm, salem...@gmail.com, juraj....@gmail.com
About the order of multiple events, I suggest you file a bug. Workarounds may depend on your use case.
Reply all
Reply to author
Forward
0 new messages