All articles
· 7 min read
The Background Sync API in production
How to use Background Sync and Periodic Background Sync to make offline writes reliable — with browser support caveats and the fallback for Safari.
TI
The InstantPWA team
Product & engineering
Background Sync is the missing piece in every "offline-first" tutorial. Without it, a queued write depends on the user reopening your tab. With it, the browser guarantees the flush the moment the network is back.
One-shot sync
// Page code
const reg = await navigator.serviceWorker.ready;
await reg.sync.register('flush-outbox');
// Service worker
self.addEventListener('sync', (event) => {
if (event.tag === 'flush-outbox') {
event.waitUntil(flushOutbox());
}
});
The browser fires sync when it detects connectivity. Runs even if your tab is closed — the service worker wakes for the event.
Periodic sync
const status = await navigator.permissions.query({ name: 'periodic-background-sync' });
if (status.state === 'granted') {
await reg.periodicSync.register('refresh-feed', { minInterval: 12 * 60 * 60 * 1000 });
}
Fires roughly every N hours when the app is installed and the device is on Wi-Fi + charging. Great for daily content refresh; useless for real-time.
Browser support
- Chrome, Edge, Opera: full support.
- Samsung Internet: one-shot only.
- Firefox, Safari: neither. Use fallback.
Fallback strategy
if ('sync' in registration) {
await registration.sync.register('flush-outbox');
} else {
window.addEventListener('online', flushOutbox);
}
Making it reliable
- Keep the queue idempotent — sync can fire twice for the same tag.
- Retry with exponential backoff inside
flushOutbox; don’t re-register on failure. - Cap queue size to bound worst-case memory.
- Log a metric on every successful flush — you’ll see the reliability curve.
Ship your install prompt in 60 seconds
InstantPWA is one line of code. Free forever for one widget, no card required.
Get started free