MV3 Background Script "running" status

Hi folks

I’m working on converting an Add on to Manifest v3. I have my updated version loaded in about:debugging, and it seems fine right now. But I’m confused about the “Running” status that is shown in this screen:

My Add on seems to be permanently “running” but I’m not sure if this will always be the case. It did stop once and enter “Stopped” state, but I’m not sure how. It’s not happened again. And if I “terminate” it, triggering one of the event listeners in my background script doesn’t seem to start it up again.

So I have the following questions:

  1. What does the background script’s “Running”/“Stopped” state represent, exactly, for a MV3 Add on?
  2. What can cause an Add on’s background script to be “Stopped”?
  3. What can cause an Add on’s background script to be “Started”?
  4. I know that in the background script, state is not saved. But if I declare variables at the top of my background script (effectively constants), are these brought back into scope when the background script wakes up?


Service workers in MV3 are not persistent like background scripts were in MV2. The worker will stop after it’s not used for a certain period of time. If you have a debugger open though, I think it stays active.

A service worker is started again when an event that has been registered to that worker is fired. For example, if I register an event using tabs.oncreated, the service worker will start (if it’s not already running) each time I open a new tab.

This is supposed to be a big performance boost because service workers aren’t eating up memory and other resources when they are not being used. Unfortunately, it is a little bit of a pain when developing a MV3 extension.

I didn’t see you had added question 4. The answer to this is, yes. When the service worker is started again, it will run all code in the JavaScript file again.

This works fine for variables with values that do not change. However, if you have a variable that is reassigned in your code, it will be reset when the service worker is started again because variables do not persist. You would need to use the Storage API for that.

It’s also important to note that this will include any function calls.

Thanks, Wesley. This is REALLY helpful. I understand this way better now.

Looks like I DID have a devtools window still connected. I see that the “Terminate background script” button does exactly ehat I thought it would, and that “Running”/“Stopped” status is showing if the background process is suspended or not.

It’s also REALLY helpful to know that this runs scripts when the process wakes. So presumably a valid approach to state is to run a function at top level in the background script that re-loads any saved background process state from storage?

I have one final question for you: is code that adds event handlers somehow ignored when the background process wakes? Or will I end up with multiple copies of the event handler?

Thanks so much.

The approach I have taken in my extension is to put all of the initialization stuff in an init() function. At the end of the init() function have save a simple boolean value in the Storage API session storage area (which is new in MV3). Then I use that boolean value to determine if the init() function needs to run again, since that storage area is cleared automatically when the user restarts their browser.

As for the event registration, I’m not entirely sure if it’s ignored. I’ve also put my event registration outside of the function and I haven’t ended up with duplicate handlers. I’ve never tried using anonymous functions as the handler, so I don’t know if that will make a difference.

Thanks for this. You replied really quickly and were amazingly helpful. :raised_hands: