AsyncLocalStorage
Last updated Apr 23, 2026
Background
Note
For compatibility dates of 2026-08-04 or later, Workers enables both nodejs_compat and nodejs_compat_v2 by default. These flags are not used for these compatibility dates. Existing projects do not need to remove them when updating their compatibility date. For earlier dates, add nodejs_compat to your Wrangler configuration file to opt in. For instructions to turn off Node.js compatibility, refer to the Node.js compatibility flag.
Cloudflare Workers provides an implementation of a subset of the Node.js AsyncLocalStorage ↗︎ API for creating in-memory stores that remain coherent through asynchronous operations.
Constructor
import { AsyncLocalStorage } from "node:async_hooks";
const asyncLocalStorage = new AsyncLocalStorage();
new AsyncLocalStorage(): AsyncLocalStorage- Returns a new
AsyncLocalStorageinstance.
Methods
getStore(): any- Returns the current store. If called outside of an asynchronous context initialized by calling
asyncLocalStorage.run(), it returnsundefined. run(storeany, callbackfunction, ...argsarguments): any- Runs a function synchronously within a context and returns its return value. The store is not accessible outside of the callback function. The store is accessible to any asynchronous operations created within the callback. The optional
argsare passed to the callback function. If the callback function throws an error, the error is thrown byrun()also. exit(callbackfunction, ...argsarguments): any- Runs a function synchronously outside of a context and returns its return value. This method is equivalent to calling
run()with thestorevalue set toundefined.
Static Methods
AsyncLocalStorage.bind(fn): function- Captures the asynchronous context that is current when
bind()is called and returns a function that enters that context before calling the passed in function. AsyncLocalStorage.snapshot(): function- Captures the asynchronous context that is current when
snapshot()is called and returns a function that enters that context before calling a given function.
Examples
Fetch Listener
import { AsyncLocalStorage } from 'node:async_hooks';
const asyncLocalStorage = new AsyncLocalStorage();
let idSeq = 0;
export default {
async fetch(req) {
return asyncLocalStorage.run(idSeq++, () => {
// Simulate some async activity...
await scheduler.wait(1000);
return new Response(asyncLocalStorage.getStore());
});
}
};
Multiple stores
The API supports multiple AsyncLocalStorage instances to be used concurrently.
import { AsyncLocalStorage } from 'node:async_hooks';
const als1 = new AsyncLocalStorage();
const als2 = new AsyncLocalStorage();
export default {
async fetch(req) {
return als1.run(123, () => {
return als2.run(321, () => {
// Simulate some async activity...
await scheduler.wait(1000);
return new Response(`${als1.getStore()}-${als2.getStore()}`);
});
});
}
};
Unhandled Rejections
When a Promise rejects and the rejection is unhandled, the async context propagates to the 'unhandledrejection' event handler:
import { AsyncLocalStorage } from "node:async_hooks";
const asyncLocalStorage = new AsyncLocalStorage();
let idSeq = 0;
addEventListener("unhandledrejection", (event) => {
console.log(asyncLocalStorage.getStore(), "unhandled rejection!");
});
export default {
async fetch(req) {
return asyncLocalStorage.run(idSeq++, () => {
// Cause an unhandled rejection!
throw new Error("boom");
});
},
};
AsyncLocalStorage.bind() and AsyncLocalStorage.snapshot()
import { AsyncLocalStorage } from "node:async_hooks";
const als = new AsyncLocalStorage();
function foo() {
console.log(als.getStore());
}
function bar() {
console.log(als.getStore());
}
const oneFoo = als.run(123, () => AsyncLocalStorage.bind(foo));
oneFoo(); // prints 123
const snapshot = als.run("abc", () => AsyncLocalStorage.snapshot());
snapshot(foo); // prints 'abc'
snapshot(bar); // prints 'abc'
import { AsyncLocalStorage } from "node:async_hooks";
const als = new AsyncLocalStorage();
class MyResource {
#runInAsyncScope = AsyncLocalStorage.snapshot();
doSomething() {
this.#runInAsyncScope(() => {
return als.getStore();
});
}
}
const myResource = als.run(123, () => new MyResource());
console.log(myResource.doSomething()); // prints 123
AsyncResource
The AsyncResource ↗︎ class is a component of Node.js' async context tracking API that allows users to create their own async contexts. Objects that extend from AsyncResource are capable of propagating the async context in much the same way as promises.
Note that AsyncLocalStorage.snapshot() and AsyncLocalStorage.bind() provide a better approach. AsyncResource is provided solely for backwards compatibility with Node.js.
Constructor
import { AsyncResource, AsyncLocalStorage } from "node:async_hooks";
const als = new AsyncLocalStorage();
class MyResource extends AsyncResource {
constructor() {
// The type string is required by Node.js but unused in Workers.
super("MyResource");
}
doSomething() {
this.runInAsyncScope(() => {
return als.getStore();
});
}
}
const myResource = als.run(123, () => new MyResource());
console.log(myResource.doSomething()); // prints 123
new AsyncResource(typestring, optionsAsyncResourceOptions): AsyncResource- Returns a new
AsyncResource. Importantly, while the constructor arguments are required in Node.js' implementation ofAsyncResource, they are not used in Workers. AsyncResource.bind(fnfunction, typestring, thisArgany)- Binds the given function to the current async context.
Methods
asyncResource.bind(fnfunction, thisArgany)- Binds the given function to the async context associated with this
AsyncResource. asyncResource.runInAsyncScope(fnfunction, thisArgany, ...argsarguments)- Call the provided function with the given arguments in the async context associated with this
AsyncResource.
Caveats
- The
AsyncLocalStorageimplementation provided by Workers intentionally omits support for theasyncLocalStorage.enterWith()↗︎ andasyncLocalStorage.disable()↗︎ methods. - Workers does not implement the full
async_hooks↗︎ API upon which Node.js' implementation ofAsyncLocalStorageis built. - Workers does not implement the ability to create an
AsyncResourcewith an explicitly identified trigger context as allowed by Node.js. This means that a newAsyncResourcewill always be bound to the async context in which it was created. - Thenables (non-Promise objects that expose a
then()method) are not fully supported when usingAsyncLocalStorage. When working with thenables, instead useAsyncLocalStorage.snapshot()↗︎ to capture a snapshot of the current context.
Was this helpful?
YesNo
On this page
{"@context":"https://schema.org","@type":"TechArticle","@id":"https://developers.cloudflare.com/workers/runtime-apis/nodejs/asynclocalstorage/#page","headline":"AsyncLocalStorage","description":"Use the Node.js AsyncLocalStorage API in Cloudflare Workers to maintain context across asynchronous operations.","url":"https://developers.cloudflare.com/workers/runtime-apis/nodejs/asynclocalstorage/","inLanguage":"en","image":"https://developers.cloudflare.com/workers/runtime-apis/nodejs/asynclocalstorage/og.png?v=fd99fd4b59a85f28","dateModified":"2026-04-23","publisher":{"@type":"Organization","name":"Cloudflare","description":"One platform for your apps, agents, and workforce. Build, secure, and scale without managing infrastructure","url":"https://www.cloudflare.com/","sameAs":["https://github.com/cloudflare","https://www.linkedin.com/company/cloudflare","https://x.com/cloudflare"],"logo":{"@type":"ImageObject","url":"https://developers.cloudflare.com/logo.svg"},"address":{"@type":"PostalAddress","streetAddress":"101 Townsend St","addressLocality":"San Francisco","addressRegion":"CA","postalCode":"94107","addressCountry":"US"},"contactPoint":[{"@type":"ContactPoint","contactType":"Customer Support","url":"https://support.cloudflare.com/","availableLanguage":["English"]},{"@type":"ContactPoint","contactType":"Sales","url":"https://www.cloudflare.com/contact/","availableLanguage":["English"]}]},"isPartOf":{"@type":"WebSite","@id":"https://developers.cloudflare.com/#website","name":"Cloudflare Docs","url":"https://developers.cloudflare.com/"}}
description: Use the Node.js Buffer API in Cloudflare Workers to manipulate binary data with encoding and decoding support. title: Buffer image: https://developers.cloudflare.com/workers/runtime-apis/nodejs/buffer/og.png?v=4a090cfa58c4281a
Documentation Index
Fetch the complete documentation index at: https://developers.cloudflare.com/workers/llms.txt
Use this file to discover all available pages before exploring further.
Docs