Skip to content

Periodic background sync: refreshing content while the app is closed

In one line: Periodic background sync lets a web app’s service worker periodically synchronize data in the background, so a PWA can show fresh content immediately on launch instead of fetching it while the user waits.

Periodic background sync downloads data in the background when the app or page is not being used, so the app’s content does not need to refresh — and does not need to show a loading spinner — after the user opens it. This is different from (non-periodic) background sync, whose most common use case is re-sending data to a server after a previous request failed; periodic background sync is about proactively refreshing content, not retrying failed requests.

The API is reached through ServiceWorkerRegistration.periodicSync, which returns a PeriodicSyncManager:

const registration = await navigator.serviceWorker.ready;
if ('periodicSync' in registration) {
try {
await registration.periodicSync.register('get-latest-news', {
minInterval: 24 * 60 * 60 * 1000,
});
} catch {
console.log('Periodic Sync could not be registered!');
}
}
  • PeriodicSyncManager.register(tag, options) registers a periodic sync request with the given tag and a minInterval (in milliseconds), returning a promise that resolves once registration completes.
  • PeriodicSyncManager.getTags() resolves with the list of tags currently registered.
  • PeriodicSyncManager.unregister(tag) removes a previously registered tag.

In the service worker, the app listens for the periodicsync event, whose PeriodicSyncEvent.tag identifies which registration fired (multiple tags can drive different tasks at different frequencies):

self.addEventListener('periodicsync', (event) => {
if (event.tag === 'get-latest-news') {
event.waitUntil(fetchAndCacheLatestNews());
}
});

Availability is gated by install and engagement

Section titled “Availability is gated by install and engagement”

Chrome only allows a web app to use periodic background sync after a person has installed it on their device and launched it as a distinct application — it is not available in the context of a regular browser tab. Because Chrome does not want unused or seldom-used web apps to gratuitously consume battery or data, it also gates access on user engagement with the installed app before granting the capability.

  • Feature-detect with 'periodicSync' in registration before calling register().
  • Only rely on periodic background sync for installed, launched (not just tabbed) PWAs — it is unavailable in a regular browser tab.
  • Pass a realistic minInterval; the browser — not your app — decides the actual sync frequency based on engagement and other signals.
  • Use distinct tag values for independent periodic tasks and check event.tag in the periodicsync handler.
  • Keep push notifications for genuinely important, user-facing updates; use periodic sync for routine content refresh instead.