AsyncLocalStorage carries request-local context across supported asynchronous operations. It helps correlate logs without passing identifiers through every function.
Before you start
You should know JavaScript promises, asynchronous errors and the distinction between a process and a request. When following a server example, identify the resource owner and the point where work completes. Try experiments locally with bounded input instead of assuming production traffic behaves like a single request.
The practical goal is to reason through this situation: Create a context containing a request ID before entering request processing. Read the walkthrough first, then try the interview exercise before opening its answer. The important part is explaining the decision and its consequences, rather than remembering a definition alone.
Step-by-step walkthrough
Step 1: Create per-request data
Generate or validate a request ID before starting processing. Avoid one mutable global variable for all requests.
Step 2: Enter an owned context
Run request work inside AsyncLocalStorage.run with a small context object.
Step 3: Verify propagation boundaries
Exercise nested promises and callback integrations, especially adapters that may not preserve the intended asynchronous context.
Worked scenario
Create a context containing a request ID before entering request processing.
import { AsyncLocalStorage } from 'node:async_hooks';
const context = new AsyncLocalStorage();
await context.run({ requestId: 'r1' }, async () => {
await Promise.resolve();
console.log(context.getStore().requestId); // r1
});Overlapping run calls carry separate stores; they do not need to overwrite a shared requestId variable.
Common mistake
A global mutable request ID mixes overlapping requests.
Verify the behavior
Run two overlapping requests with reversed completion order. Verify each log retains its own ID and background work does not retain unnecessary request objects.
Interview exercise
Check propagation reliability.
Answer and reasoning
Test nested promises and callback integrations, and keep context small so long-lived tasks do not retain unnecessary request data.
Continue learning
Compare the scenario with the Node.js interview questions and test your understanding with the Node.js MCQs. For terminology and implementation details, consult the reference material.