Chrome alarms are very unreliable for timer extentions + some other suggestions (offscreen etc)

20 views
Skip to first unread message

J Benjamin Dsouza

unread,
2:35 AM (7 hours ago) 2:35 AM
to Chromium Extensions

Hello!

I have a focus timer/website blocker extension. But this post is mostly about the focus timer.

Before manifest v3, it was very easy to run a long-running task such as a setInterval, as it persisted. But after v3, it caused a lot of issues since the lifecycle of the worker is short-lived; APIs like setInterval wouldn’t work as expected.

Since then, I’ve been using alarms, and here are a few observations

  1. They’re very unreliable and have a lot of drift
  2. You can’t run them every second
  3. Experience between the unpacked version and the runtime prod versions is very different.

I’m aware all these are mentioned in the docs, but I have a proposal

Issue 1 and Issue 2

While I understand alarms can be very heavy on the user's system and running them each second requires significant memory and causes perf issues, we need something better, something more accurate.

Currently, even scheduling a single alarm, 15m or 25m in the future, it fires unreliably. Always firing a few seconds late.

My suggestion is that even if you don’t support minute accuracy, it would be nice to have accurate scheduling. Just throwing some ideas around: maybe allow for a pool of 5-6 accurate schedules per hour, or allocate some memory or give the devs access to a queue (with limits), that they can push schedules into?

Issue 3

Testing alarms is a pain on unpacked version and runtime prod version. Everything seems to work really well on the local machine, but as soon as you try the live runtime version, everything breaks. It becomes really hard to pinpoint issues when alarms are involved. On local versions, Chrome lets you run alarms up to minute accuracy. This isn’t the case on prod.

My suggestion would be to have some kind of flag that allows you to run the exact runtime env for unpacked versions. That way it becomes easier to debug alarm drift/delay issues.

My workaround

Right now, my workaround is a bit wonky. I’m using offscreen and alarms to run my timer. And I’m being very pragmatic with my code; I only run the alarms once a minute (since I don’t care when it fires if its not < 60s), and once the timer duration reaches < 60, i hand the controls over to an offscreen which then runs a setInterval. I want the ending to be very accurate and fire exactly at the end time.

Before using this workaround, the alarms would fire at unreliable end times many seconds after the actual timer had ended. This caused a lot of my users to think the extension is broken (cause it stopped at 0:00 and didn’t end the timer session). And it was really hard to pinpoint this issue because it worked fine unpacked. I have tested this on the runtime version, and it seems to hold. I’m using “WORKER” reason for the offscreen, as it keeps the offscreen open indefinitely.

My suggestion would be to introduce another official reason called “INTERVAL” or “TIMER”.


TLDR using claude
  • Alarm accuracy/drift: Even single alarms scheduled minutes out fire several seconds late, with no way to tighten this. Not asking for full setInterval-level precision — just a bounded way to get more accurate scheduling (e.g. a small quota of high-precision timers per hour) without opening up unrestricted per-second alarms.
  • Unpacked vs. packed behavior diverges: Unpacked extensions have no alarm throttling, so drift/timing bugs are invisible locally and only show up once published. Need a way to simulate prod throttling while testing unpacked, so this class of bug is debuggable before shipping.
  • No official "keep this context alive for a timer" pattern: Currently working around this with an offscreen document using the WORKERS reason to run setInterval for the final accurate countdown. Suggest formalizing this with a dedicated offscreen reason (e.g. TIMER/INTERVAL) so it's a documented, sanctioned pattern instead of a repurposed workaround.

Anyways that's all I can think of right now. Hope you can consider my suggestions!

P.S: Chrome store reviews got faster; thanks to that, I was able to push multiple hot fixes for my extension. Please convey my thanks to the review team.

-Ben

Oliver Dunk

unread,
4:17 AM (6 hours ago) 4:17 AM
to J Benjamin Dsouza, Chromium Extensions
Hi Ben,

Making the alarms API more reliable has been a focus of mine, so you have my attention. That said, I am a little unsure how much of what you have mentioned is unexpected / would be something we are likely to change.

Currently, even scheduling a single alarm, 15m or 25m in the future, it fires unreliably. Always firing a few seconds late.

Is this really a problem? Could you share your use case? I'm not aware of any intentional delay, but I can imagine it taking a few seconds if the service worker needs to be started depending on your machine specs. You later say "I don’t care when it fires if its not < 60s" which makes it sound like perhaps this isn't too important.

On local versions, Chrome lets you run alarms up to minute accuracy. This isn’t the case on prod.

Alarms are just as accurate for packed and unpacked extensions, although in packed extensions the minimum interval for an alarm is 30 seconds. Does this match what you are seeing or are you seeing other signs that the accuracy is lower than expected?

Thanks for the kind words on the review process - I will pass those on!
Oliver Dunk | DevRel, Chrome Extensions | https://developer.chrome.com/ | London, GB


--
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 visit https://groups.google.com/a/chromium.org/d/msgid/chromium-extensions/b5353c0f-a775-4edb-899e-74e5c9e70986n%40chromium.org.

J Benjamin Dsouza

unread,
5:07 AM (5 hours ago) 5:07 AM
to Chromium Extensions, Oliver Dunk, Chromium Extensions, J Benjamin Dsouza

>  I am a little unsure how much of what you have mentioned is unexpected / would be something we are likely to change.

I can only speak from my experience as I have no idea how the internals of Chrome or alarms work. But from what I've observed, at least in the older versions of my extention (until yday), is that only using alarms for high accuracy tasks/calls is very unreliable, as they fire a little late. Sometimes they work normally, but most times theres a delay of 15-30s. 

In old versions of my extension (until i did a rewrite last week), the alarms used to run every second. Unpacked, this wasn't a problem as Chrome runs it upto per second accuracy. So my timer worked fine. The problem arises when it's shipped to the Chrome Store; the runtime versions get throttled significantly. So I'm assuming that's why there's a delay or drift with the timer. 

Some Context about my extention,

And all this has to do with how my extension works. Until recently, I was using counters + alarms to measure time in my extension; even though unreliable, it didn't cause much issue (I was running alarms each second using alarms.when). The only issue was drift and because of this, it didn't bother me that the timers fired slowly (the timer always turns off automatically, regardless of drift, if the counter reaches 0). Then I made the change to make it more accurate; now it uses Date.now() to measure the clock (start time and endtime). When I pushed to the Chrome Store, and tested the live version, even though the timer was now accurate (I was running the alarms every 10 seconds), the last one always missed or was delayed by a few seconds. 

I tried scheduling an alarm to run at a specific time, say n + 25m also fails at runtime (works fined in unpacked). Always delayed by 10-15 seconds. I don't know why this happens. Lots of my users had raised this issue too.

> You later say "I don’t care when it fires if its not < 60s" which makes it sound like perhaps this isn't too important.

Yes, I mean for most of the timer's duration it doesn't matter. As I only use it to update the Chrome badge to show time (15m, 25m etc). But the last 60 seconds of a session matter, as when the clock ends, it fires a message to display a dialog box. Only using alarms makes this event fire a lot later than it should. So offscreen, fires this event accurately and ends the timer.

For context, this is my extension (it works now cuz the last 60s countdown is passed of to offscript)


Set a timer for 00:25, (uses the offscreen controller to count time). Then try 5:00; it uses alarms that fire once per min, switches to offscreen when <1:00.

I hope all this makes sense. Happy to clarify some more!

Ben
Reply all
Reply to author
Forward
0 new messages