SharedArrayBuffer
BaselineWidely available *
This feature is well established and works across many devices and browser versions. It’s been available across browsers since December 2021.
* Some parts of this feature may have varying levels of support.
TheSharedArrayBuffer
object is used to represent a generic raw binary data buffer, similar to theArrayBuffer
object, but in a way that they can be used to create views on shared memory. ASharedArrayBuffer
is not aTransferable Object, unlike anArrayBuffer
which is transferable.
Description
To share memory usingSharedArrayBuffer
objects from one agent in the cluster to another (an agent is either the web page's main program or one of its web workers),postMessage
andstructured cloning is used.
The structured clone algorithm acceptsSharedArrayBuffer
objects and typed arrays mapped ontoSharedArrayBuffer
objects. In both cases, theSharedArrayBuffer
object is transmitted to the receiver resulting in a new, privateSharedArrayBuffer
object in the receiving agent (just as forArrayBuffer
). However, the shared data block referenced by the twoSharedArrayBuffer
objects is the same data block, and a side effect to the block in one agent will eventually become visible in the other agent.
const sab = new SharedArrayBuffer(1024);worker.postMessage(sab);
Shared memory can be created and updated simultaneously in workers or the main thread. Depending on the system (the CPU, the OS, the Browser) it can take a while until the change is propagated to all contexts. To synchronize,atomic operations are needed.
SharedArrayBuffer
objects are used by some web APIs, such as:
Security requirements
Shared memory and high-resolution timers were effectivelydisabled at the start of 2018 in light ofSpectre.In 2020, a new, secure approach has been standardized to re-enable shared memory.
To use shared memory your document must be in asecure context andcross-origin isolated.You can use theWindow.crossOriginIsolated
andWorkerGlobalScope.crossOriginIsolated
properties to check if the document is cross-origin isolated:
const myWorker = new Worker("worker.js");if (crossOriginIsolated) { const buffer = new SharedArrayBuffer(16); myWorker.postMessage(buffer);} else { const buffer = new ArrayBuffer(16); myWorker.postMessage(buffer);}
When cross-origin isolated,postMessage()
no longer throws forSharedArrayBuffer
objects, and shared memory across threads is therefore available.
API availability
Depending on whether the above security measures are taken, the various memory-sharing APIs have different availabilities:
- The
Atomics
object is always available. SharedArrayBuffer
objects are in principle always available, but unfortunately the constructor on the global object is hidden, unless the two headers mentioned above are set, for compatibility with web content. There is hope that this restriction can be removed in the future.WebAssembly.Memory
can still be used to get an instance.- Unless the two headers mentioned above are set, the various
postMessage()
APIs will throw forSharedArrayBuffer
objects. If they are set,postMessage()
onWindow
objects and dedicated workers will function and allow for memory sharing.
WebAssembly shared memory
WebAssembly.Memory
objects can be created with theshared
constructor flag. When this flag is set totrue
, the constructedMemory
object can be shared between workers viapostMessage()
, just likeSharedArrayBuffer
, and the backingbuffer
of theMemory
object is aSharedArrayBuffer
. Therefore, the requirements listed above for sharing aSharedArrayBuffer
between workers also apply to sharing aWebAssembly.Memory
.
The WebAssembly Threads proposal also defines a new set ofatomic instructions. Just asSharedArrayBuffer
and its methods are unconditionally enabled (and only sharing between threads is gated on the new headers), the WebAssembly atomic instructions are also unconditionally allowed.
Growing SharedArrayBuffers
SharedArrayBuffer
objects can be made growable by including themaxByteLength
option when calling theSharedArrayBuffer()
constructor. You can query whether aSharedArrayBuffer
is growable and what its maximum size is by accessing itsgrowable
andmaxByteLength
properties, respectively. You can assign a new size to a growableSharedArrayBuffer
with agrow()
call. New bytes are initialized to 0.
These features make growingSharedArrayBuffer
s more efficient — otherwise, you have to make a copy of the buffer with a new size. It also gives JavaScript parity with WebAssembly in this regard (Wasm linear memory can be resized withWebAssembly.Memory.prototype.grow()
).
For security reasons,SharedArrayBuffer
s cannot be reduced in size, only grown.
Constructor
SharedArrayBuffer()
Creates a new
SharedArrayBuffer
object.
Static properties
SharedArrayBuffer[Symbol.species]
Returns the constructor used to construct return values from
SharedArrayBuffer
methods.
Instance properties
These properties are defined onSharedArrayBuffer.prototype
and shared by allSharedArrayBuffer
instances.
SharedArrayBuffer.prototype.byteLength
The size, in bytes, of the array. This is established when the array is constructed and can only be changed using the
SharedArrayBuffer.prototype.grow()
method if theSharedArrayBuffer
is growable.SharedArrayBuffer.prototype.constructor
The constructor function that created the instance object. For
SharedArrayBuffer
instances, the initial value is theSharedArrayBuffer
constructor.SharedArrayBuffer.prototype.growable
Read-only. Returns
true
if theSharedArrayBuffer
can be grown, orfalse
if not.SharedArrayBuffer.prototype.maxByteLength
The read-only maximum length, in bytes, that the
SharedArrayBuffer
can be grown to. This is established when the array is constructed and cannot be changed.SharedArrayBuffer.prototype[Symbol.toStringTag]
The initial value of the
[Symbol.toStringTag]
property is the string"SharedArrayBuffer"
. This property is used inObject.prototype.toString()
.
Instance methods
SharedArrayBuffer.prototype.grow()
Grows the
SharedArrayBuffer
to the specified size, in bytes.SharedArrayBuffer.prototype.slice()
Returns a new
SharedArrayBuffer
whose contents are a copy of thisSharedArrayBuffer
's bytes frombegin
, inclusive, up toend
, exclusive. If eitherbegin
orend
is negative, it refers to an index from the end of the array, as opposed to from the beginning.
Examples
Creating a new SharedArrayBuffer
const sab = new SharedArrayBuffer(1024);
Slicing the SharedArrayBuffer
sab.slice(); // SharedArrayBuffer { byteLength: 1024 }sab.slice(2); // SharedArrayBuffer { byteLength: 1022 }sab.slice(-2); // SharedArrayBuffer { byteLength: 2 }sab.slice(0, 1); // SharedArrayBuffer { byteLength: 1 }
Using it in a WebGL buffer
const canvas = document.querySelector("canvas");const gl = canvas.getContext("webgl");const buffer = gl.createBuffer();gl.bindBuffer(gl.ARRAY_BUFFER, buffer);gl.bufferData(gl.ARRAY_BUFFER, sab, gl.STATIC_DRAW);
Specifications
Specification |
---|
ECMAScript® 2026 Language Specification # sec-sharedarraybuffer-objects |
Browser compatibility
See also
Atomics
ArrayBuffer
- JavaScript typed arrays guide
- Web Workers
- Shared Memory – a brief tutorial in the TC39 ecmascript-sharedmem proposal
- A Taste of JavaScript's New Parallel Primitives on hacks.mozilla.org (2016)
- COOP and COEP explained by the Chrome team (2020)
Cross-Origin-Opener-Policy
Cross-Origin-Embedder-Policy
Cross-Origin-Resource-Policy
Window.crossOriginIsolated
andWorkerGlobalScope.crossOriginIsolated
- SharedArrayBuffer updates in Android Chrome 88 and Desktop Chrome 92 on developer.chrome.com (2021)