Browser / Field Notes
Interactive guide · 01

Many tabs.
One shared resource.

A hands-on guide to the Web Locks API. Reproduce a race, line up competing tasks, and let one upload own the work.

An interactive adaptation of The Web Locks API: A Lifesaver When It Matters by zhangxinxu.

Checking Web Locks availability…
01 / The problem

A check is not a reservation.

Reading a value and writing it back are separate operations. Two tabs can both read zero before either writes one. This deterministic, in-memory simulation exposes that same lost-update pattern without changing your storage.

Code:javascript · executable demo
Result:Simulated tabs · deliberately interleaved
Expected count2
Actual count0
Lost updates0
Ready. Both callers will read before either writes.

A localStorage flag also needs stale-lock recovery. BroadcastChannel delivers messages, but does not itself grant exclusive access.

02 / Take turns

One name. One exclusive owner.

Requests for the same exclusive lock wait their turn. The browser holds the lock until the callback’s returned promise settles. Here, three tasks safely update a counter in this page.

Code:javascript · real Web Locks
Result:Each task holds the lock for 800 ms
Ready. The counter starts at zero on each run.

Only cooperating callers are synchronized. Use the same lock name around every operation that needs protection.

03 / The article’s use case

Let one tab handle the upload.

With ifAvailable: true, a competing request receives null immediately. Start an upload, then try a competing caller—or open this page in another tab at the same origin.

Code:javascript · acquisition + cleanup
Result:Real lock · simulated transfer · no file sent
field-notes.zip0%
Ready. Lock name: web-locks-lab:upload

The option is case-sensitive: ifAvailable. This corrects the article’s sample typo. The async callback awaits the entire transfer; cancellation ends the simulated work before releasing the lock.

04 / Choose an access policy

Shared readers. Exclusive writers.

Shared locks can coexist. An exclusive lock waits for conflicting holders to finish. Add two readers, then a writer, and watch the order. An AbortSignal can cancel a request while it is waiting.

Code:javascript · mode + signal
Result:Each owner holds its lock for 4 seconds
Ready. Readers and writers use the same document lock.

Aborting a request signal does not stop a callback that already owns its lock. The optional steal flag forcibly takes ownership but does not stop the previous owner’s code; it is intentionally omitted from these controls.

05 / Look inside

See who owns the work.

navigator.locks.query() returns a snapshot of held and pending locks. Start a demo above and refresh to see its lock name, mode, and client identifier.

Code:javascript · LockManager.query()
Result:Snapshot · filtered to this lab’s lock names
No snapshot yet.

A snapshot is for observation, not acquisition: its contents can change immediately. Use request() to coordinate work.