Everything, Everywhere
Verified Specification | Standardized Formulas | Instant Precision
Secure & Private (Zero Data Retention) Free Access • No Sign-Up
W3C Web Locks API Leader Election BroadcastChannel Pub/Sub

Web Locks API, BroadcastChannel & Multi-Tab Sync Studio

Architect robust multi-tab web applications. Simulate navigator.locks shared and exclusive locks, test instant failover leader elections, broadcast reactive state changes via BroadcastChannel, and observe guaranteed deadlock-free tab crash recoveries.

1. Simulated Browser Tab Cluster (Same Origin)

2. Lock Resource Table (navigator.locks.query())

3. Production Multi-Tab Leader Election & Sync Pattern

// TypeScript: Resilient Multi-Tab Leader Election & Sync
const syncBus = new BroadcastChannel('app_state_channel');

async function electLeader(onElected: () => void) {
  if (!('locks' in navigator)) {
    console.warn('Web Locks API not supported; falling back to single-tab mode');
    return;
  }

  // Request exclusive lock on 'singleton_leader'
  await navigator.locks.request('singleton_leader', async (lock) => {
    console.log('[Leader] Lock acquired. This tab is now the active leader.');
    syncBus.postMessage({ type: 'LEADER_ELECTED', tabId: window.name });
    onElected();

    // Hold the lock indefinitely until this tab closes or crashes
    await new Promise(() => {});
  });
}

// Transactional Mutex across tabs
async function executeAtomicDbMutation<T>(mutationFn: () => Promise<T>): Promise<T> {
  return await navigator.locks.request('idb_write_mutex', { mode: 'exclusive' }, async () => {
    const result = await mutationFn();
    syncBus.postMessage({ type: 'DATA_UPDATED', timestamp: Date.now() });
    return result;
  });
}

⚠️ 5 Fatal Traps in Web Locks & Multi-Tab Architectures

1. Permanent Lock Holding via Unresolving Promises in Mutexes

The Web Lock is released ONLY when the callback promise resolves or rejects. If an asynchronous database operation hangs (e.g. awaiting an unfulfilled network response without an AbortSignal timeout), the lock remains frozen forever, permanently starving all other browser tabs from writing to IndexedDB.

2. Inadvertent Deadlocks through Nested Lock Acquisition

If Tab 1 acquires Lock A and requests Lock B, while Tab 2 acquires Lock B and requests Lock A, an unrecoverable classic deadlock occurs. Web Locks does NOT automatically detect deadlocks. Always acquire locks in a globally consistent alphabetical order or use lock stealing (steal: true).

3. BroadcastChannel Memory Leaks from Missing 'close()'

Creating new BroadcastChannel() inside short-lived Single Page Application (SPA) view components or Web Workers without invoking channel.close() upon component unmount retains the event listener in the browser engine, leaking memory and duplicating message handler executions.

4. Overlooking 'ifAvailable: true' for Non-Blocking Probes

When a background worker wants to perform opportunistic cache cleanup, queuing behind a heavy user transaction degrades responsiveness. Developers should pass { ifAvailable: true }. If the lock is currently held, the callback is invoked with null, allowing immediate non-blocking skip.

5. Cross-Origin iframes Without Permissions Delegation

Web Locks are strictly scoped to the origin (scheme + domain + port). However, if an embedded cross-origin iframe attempts to coordinate with parent or sibling frames, navigator.locks operates in an entirely isolated namespace and provides zero mutual exclusion against the host page.

Frequently Asked Technical Questions

What is the Web Locks API and why is it superior to localStorage mutex hacks?+
The W3C Web Locks API (navigator.locks) provides true asynchronous, operating-system-backed mutual exclusion primitives across browsing contexts (tabs, windows, web workers, and Service Workers) of the same origin. Historically, web developers attempted to coordinate tabs using localStorage events or atomic flags, which suffered from severe race conditions, unhandled tab crashes leaving permanently orphaned deadlocks, and high CPU polling churn. Web Locks guarantees atomic FIFO ordering and automatic lock reclamation upon tab termination.
What is the difference between "exclusive" and "shared" locks?+
An "exclusive" lock (default) permits only one execution context to hold the lock at any given time; all subsequent requests wait in a FIFO queue until the holder resolves its promise. A "shared" lock implements the classic reader-writer pattern: multiple contexts can hold the same shared lock concurrently (e.g. reading from IndexedDB), but any pending exclusive lock request (e.g. writing a database schema migration) blocks until all current shared locks are released.
How does Web Locks make multi-tab Leader Election trivial?+
Leader election coordinates singleton tasks (such as maintaining a single WebSocket connection to the backend or polling notifications). A tab requests an exclusive lock: `navigator.locks.request("app_leader", async (lock) => { becomeLeader(); await new Promise(() => {}); });`. The first tab to request it holds the lock indefinitely. If the leader tab is closed or crashes, the browser immediately releases the lock, and the next queued tab automatically acquires it and assumes leadership with zero network downtime.
What happens to a held lock when a browser tab crashes or is force-killed?+
Because Web Locks are managed directly by the browser process and operating system kernel, if a tab process crashes, is killed by an OS OOM killer, or has its window closed, the browser engine automatically detects the teardown of the browsing context and releases all locks held or requested by that context. Deadlocks caused by crashed processes are mathematically impossible under Web Locks, unlike manual cookie or storage flags.
How do BroadcastChannel and Web Locks combine to form atomic client state architectures?+
Web Locks provides mutual exclusion, while the BroadcastChannel API provides low-latency, cross-tab pub/sub messaging. When a tab needs to perform an atomic state mutation (e.g. updating an offline shopping cart in IndexedDB), it acquires an exclusive Web Lock, performs the database transaction, broadcasts an `UPDATE_SYNC` event via BroadcastChannel with the transaction ID, and releases the lock. Other tabs receive the broadcast and refresh their UI without race conditions.
Sponsored Utility
While You're Here
Sponsored Recommendations
Advertisement