← Chrome 148 reference

v148 · web api · shipped

Extended lifetime shared workers

A new extendedLifetime: true option on the SharedWorker constructor keeps the worker alive after all its clients have unloaded. This lets pages hand off in-flight async work — network requests, IndexedDB writes, analytics flushes — to a shared worker that outlives any individual page, without needing a Service Worker.

at a glance

Constructor optionnew SharedWorker(url, { extendedLifetime: true })
EffectWorker stays alive after the last client unloads; terminates when it becomes idle (no pending tasks, microtasks, or Web Locks)
Standard SharedWorkerTerminates as soon as the last client disconnects
Shipped inChrome 148 (desktop + Android + WebView)
Origin trial ranChrome 139 – 148
ChromeStatus5138641357373440 — Extended lifetime shared workers
Blog postExtended lifetime shared workers — Chrome for Developers
Source: chromestatus and blink-dev ITS, May 2026.

why it exists

Pages frequently need to complete async work (save data, flush events, finish network requests) after the user navigates away. navigator.sendBeacon() covers fire-and-forget POST, but not complex multi-step flows. Service Workers can run after page unload but add complexity — a shared scope, update lifecycle, and push infrastructure. Extended lifetime shared workers fill the gap: a shared worker with extendedLifetime: true stays alive long enough to complete in-progress work, then terminates naturally once idle.

Source: blink-dev ITS and origin trial blog post, May 2026.

usage

// Page code: create (or connect to) an extended-lifetime worker
const worker = new SharedWorker('/workers/persistence.js', {
  extendedLifetime: true
});

worker.port.start();

// Hand off work before unloading
window.addEventListener('pagehide', () => {
  worker.port.postMessage({ type: 'flush', data: pendingEvents });
});
// persistence.js — shared worker
self.onconnect = (e) => {
  const port = e.ports[0];
  port.onmessage = async ({ data }) => {
    if (data.type === 'flush') {
      // Worker stays alive to complete this even after the page unloads
      await fetch('/api/events', {
        method: 'POST',
        body: JSON.stringify(data.data)
      });
    }
  };
  port.start();
};
Source: extended lifetime shared workers blog post, May 2026.

lifetime rules

ConditionResult
All clients connected — normal operationWorker runs normally
Last client disconnects — standard SharedWorkerWorker terminates immediately
Last client disconnects — extendedLifetime: trueWorker stays alive until idle (no tasks, no pending locks)
Worker holds a Web Lock indefinitelyWorker will not terminate — this is a foot-gun to avoid
Extended workers cannot be mixed with standard workersA standard and extended-lifetime worker with the same URL are treated as separate workers
Source: blink-dev ITS — Extended lifetime shared workers, May 2026.

see also