Extension service workers respond to both the [standard service worker events](https://developer.mozilla.org/docs/Web/API/ServiceWorkerGlobalScope#events) and to events in extension namespaces. They are presented together because often one type follows another during an extension's use.

## Installation

Installation occurs when the user installs or updates a service worker from the
Chrome Web Store or when they [load or update an unpacked extension](https://developer.chrome.com/docs/extensions/get-started/tutorial/hello-world#load-unpacked)
using the `chrome://extensions` page. Three events occur, in this order:

1. `install` (service worker event)
2. `chrome.runtime.onInstalled` (extension event)
3. `activate` (service worker event)

### ServiceWorkerRegistration.install

The first event fired during installation is a web service worker's [install](https://developer.mozilla.org/docs/Web/API/ServiceWorkerGlobalScope/install_event) event.

### chrome.runtime.onInstalled

Next is the extension's [`onInstalled`](https://developer.chrome.com/docs/extensions/reference/api/runtime#event-onInstalled) event, which is fired when the extension (not the service worker) is first installed, when the extension is updated to a new version, and when Chrome is updated to a new version. Use this
event to set a state or for one-time initialization, such as a [context menu](https://developer.chrome.com/docs/extensions/reference/api/contextMenus).

    chrome.runtime.onInstalled.addListener((details) => {
      if(details.reason !== "install" && details.reason !== "update") return;
      chrome.contextMenus.create({
        "id": "sampleContextMenu",
        "title": "Sample Context Menu",
        "contexts": ["selection"]
      });
    });

### ServiceWorkerRegistration.active

Finally, the service worker's [activate](https://developer.mozilla.org/docs/Web/API/ServiceWorkerGlobalScope/activate_event) event is fired. Note that unlike web service workers, this event is fired immediately after installation of an extension because there is nothing comparable to a page reload in an extension.

## Extension startup

When a user profile starts, the [`chrome.runtime.onStartup`](https://developer.chrome.com/docs/extensions/reference/api/runtime#event-onStartup) event fires but no service worker events are invoked.

## Idle and shutdown

Normally, Chrome terminates a service worker when one of the following conditions is met:

- After 30 seconds of inactivity. Receiving an event or calling an extension API resets this timer.
- When a single request, such as an event or API call, takes longer than 5 minutes to process.
- When a [`fetch()`](https://developer.mozilla.org/docs/Web/API/fetch) response takes more than 30 seconds to arrive.

Events and calls to extension APIs reset these timers, and if the service worker has gone dormant, an incoming event will revive them. Nevertheless, you should design your service worker to be resilient against unexpected termination.

To optimize the resource consumption of your extension, avoid keeping your service worker alive indefinitely if possible. Test your extensions to ensure that you're not doing this unintentionally.

### Persist data rather than using global variables

Any global variables you set will be lost if the service worker shuts down. Instead of using global variables, save values to storage. Your options are listed.

> [!NOTE]
> **Note:** The Web Storage API is not available for extension service workers.

[chrome.storage API](https://developer.chrome.com/docs/extensions/reference/api/storage)
:   An extension API that offers multiple types of storage; local, session, managed (domain), and sync. This API stores JSON objects identified and retrieved with developer-defined keys. This type of storage isn't removed when a user clears the web cache.

[IndexedDB API](https://developer.mozilla.org/docs/Web/API/IndexedDB_API)
:   A low-level API for client-side storage of structured data, including files and blobs. This API provides primitives for creating transactional data storage and retrieval. Although this API is often too complicated for some use cases, a number of [third-party](https://developer.mozilla.org/docs/Web/API/IndexedDB_API#see_also) storage solutions are built on top of it.

[CacheStorage API](https://developer.mozilla.org/docs/Web/API/CacheStorage)
:   A persistent storage mechanism for Request and Response object pairs. This API was designed specifically for web service workers and is used to retrieve data from an endpoint. There are a variety of ways to use this API depending on whether and how critical it is that users see up-to-date data. For more information, see [The Offline Cookbook](https://web.dev/articles/offline-cookbook). Unless you're specifically proxying network requests using the fetch handler, you should use `chrome.storage`.

### Choose a minimum Chrome version

Since the release of Manifest V3, we've made several improvements to service worker lifetimes. This means that if your Manifest V3 extension supports earlier versions of Chrome, there are conditions you will need to be aware of. If these conditions don't affect your extension, you can move on from this section. If they do, consider specifying a [minimum Chrome version](https://developer.chrome.com/docs/extensions/reference/manifest/minimum-chrome-version) in your manifest.

#### Chrome 120

Alarms can now be set to a minimum period of 30s to match the service worker lifecycle. See [`chrome.alarms`](https://developer.chrome.com/docs/extensions/reference/api/alarms) for more details.

#### Chrome 118

Active debugger sessions created using the [`chrome.debugger`](https://developer.chrome.com/docs/extensions/reference/api/debugger) API now keep the service worker alive. This prevents service workers from timing out during calls for this API.

#### Chrome 116

Chrome 116 introduced the following service worker lifetime improvements:

- Active [`WebSocket`](https://developer.mozilla.org/docs/Web/API/WebSockets_API) connections now extend extension service worker lifetimes. Sending or receiving messages across a `WebSocket` in an extension service worker resets the service worker's idle timer.

- Additional extension APIs are allowed to go past the five-minute timeout period for extension service workers. These APIs display a user prompt and thus may reasonably take longer than five minutes to resolve. These include [`desktopCapture.chooseDesktopMedia()`](https://developer.chrome.com/docs/extensions/reference/api/desktopCapture#method-chooseDesktopMedia), [`identity.launchWebAuthFlow()`](https://developer.chrome.com/docs/extensions/reference/api/identity#method-launchWebAuthFlow), [`management.uninstall()`](https://developer.chrome.com/docs/extensions/reference/api/management#method-uninstall), and [`permissions.request()`](https://developer.chrome.com/docs/extensions/reference/api/permissions#method-request).

#### Chrome 114

Sending a message with [long-lived messaging](https://developer.chrome.com/docs/extensions/develop/concepts/messaging#connect) keeps the service worker alive. Opening a port no longer
resets the timers.

#### Chrome 110

Extension API calls reset the timers. Before this, only running event handlers would keep a service worker alive. Any events that were queued, but for which a handler had not been called wouldn't cause a reset.

#### Chrome 109

Messages sent from an offscreen document reset the timers.

#### Chrome 105

Connecting to a native messaging host using [`chrome.runtime.connectNative()`](https://developer.chrome.com/docs/extensions/reference/api/runtime#method-connectNative) will keep a service worker alive. If the host process crashes or is shut down, the port is closed and the service worker will terminate after timers complete. Guard against this by calling `chrome.runtime.connectNative()` in the port's onDisconnect event handler.