Provides functions to track asynchronous resources
Called when a promise starts or ends, receiving an ID
AsyncLocalStorage is fine and stable
React useContext() 랑 비슷
(1) It overlays a current execution context pointer on top of the async resource graph to automatically propagate values. Rather than storing "in one place" like a global variable, it stores in a context grouped by async chain (request chain).
How does AsyncLocalStorage have a separate store for each request? Node internally creates an async resource (Timeout, Promise, FSReq, TCPWrap, etc.) whenever an asynchronous operation is created. Each resource has a unique
asyncId, and when a new resource is created, it has a triggerAsyncId indicating "who created it". In other words, asynchronous operations form a parent-child relationship graph. So when you call als.run(store, fn) at the request starting point, storage can be safely propagated to all async resources created during fn execution; there is a store that is commonly referenced by async resources created in the request chainconst http = require('node:http'); const { AsyncLocalStorage } = require('node:async_hooks'); const storage = new AsyncLocalStorage(); http.createServer((req, res) => { storage.run({ requestId: Date.now() }, () => { log('Request start'); setTimeout(() => { log('Processing done'); res.end('OK'); }, 200); }); }).listen(3000); function log(msg) { const store = storage.getStore(); console.log(`[${store?.requestId ?? 'no-context'}] ${msg}`); }
However, note that ALS can break in certain cases: when the request starting point is not properly wrapped with
run(): store becomes undefined, libraries/patterns that break context propagation: (certain native N-API addons, worker thread boundaries are thread-local so they're separate) Raw async_hooks are Experimental
const async_hooks = require('async_hooks'); async_hooks.createHook({ init(asyncId, type, triggerAsyncId) { log(`INIT: asyncId: ${asyncId} / type: ${type} / trigger: ${triggerAsyncId}`); }, destroy(asyncId) { log(`DESTROY: asyncId: ${asyncId}`); }, }).enable();
executionAsyncId()
nest
aws lambda

Seonglae Cho

