Back to 20 Concepts
internalsAdvanced

AsyncLocalStorage & Distributed Tracing Context

AsyncLocalStorage provides thread-local storage semantics across asynchronous execution chains, allowing correlation IDs and user contexts to propagate automatically without prop-drilling.

Intuitive Mental Model

The VIP Wristband: Once a guest puts on a color-coded wristband at the door, every ride, restaurant, and booth inside the amusement park knows their VIP status without asking their name again.

Node.js ESM / CJS ImplementationNode.js v22 LTS
import { AsyncLocalStorage } from 'async_hooks';

const traceStorage = new AsyncLocalStorage<{ requestId: string }>();

function log(msg: string) {
  const store = traceStorage.getStore();
  console.log(`[${store?.requestId || 'UNKNOWN'}] ${msg}`);
}

async function handleRequest(reqId: string) {
  // Runs entire async chain within isolated context store:
  await traceStorage.run({ requestId: reqId }, async () => {
    log('Step 1: Authenticating user...');
    await new Promise(r => setTimeout(r, 50));
    log('Step 2: Querying database...');
  });
}

Key Architectural Takeaways

  • Propagates context (request ID, tenant ID, auth session) across async/await and callback boundaries.
  • Powers modern APM loggers (Datadog, OpenTelemetry, Pino) and Next.js request headers.
  • Minimal overhead: implemented with native V8 AsyncHooks bindings.
Common Production Mistake

Mutating AsyncLocalStorage store state concurrently across parallel branches without scoping.

Recommended Solution

Treat objects stored inside AsyncLocalStorage as immutable records.