14 views
AsyncLocalStorage (ALS) is the right default for request IDs and tenant context — until a 50k RPS gateway pays for a store enter/exit on every hop through middleware, ORM, and fetch. Measure the overhead on your Node version, then choose ALS, explicit params, or a hybrid.
⚡ TL;DR: Benchmark ALS vs explicit ctx args on hot handlers; keep one ALS store for correlation; don’t nest stores per library; disable ALS in ultra-hot pure functions. Pair with Node Diagnostic Channels and Node.js Event Loop Lag p99.
AsyncLocalStorage Overhead: production guidance
typescript
Run on the same Node major as production. If ALS adds single-digit percent on a CPU-bound microbench, real I/O-bound APIs often absorb it — but gateways that already fight for microseconds should stay skeptical.
// scripts/bench-als.ts
import { AsyncLocalStorage } from "node:async_hooks";
import { performance } from "node:perf_hooks";
const als = new AsyncLocalStorage<{ reqId: string }>();
function bare(n: number) {
let x = 0;
for (let i = 0; i < n; i++) x += i;
return x;
}
function withAls(n: number) {
return als.run({ reqId: "b" }, () => {
let x = 0;
for (let i = 0; i < n; i++) {
als.getStore(); // typical middleware read
x += i;
}
return x;
});
}
function bench(fn: (n: number) => number) {
const n = 5_000_000;
const t0 = performance.now();
fn(n);
return performance.now() - t0;
}
console.log({ bare: bench(bare), als: bench(withAls) });
Lean context pattern
typescript
// lib/context.ts
import { AsyncLocalStorage } from "node:async_hooks";
export type ReqCtx = { reqId: string; tenantId: string };
export const reqAls = new AsyncLocalStorage<ReqCtx>();
export function getCtx(): ReqCtx {
const s = reqAls.getStore();
if (!s) throw new Error("missing_request_context");
return s;
}
// ✅ Hot pure math / codec path — pass args, skip ALS
export function encodeInvoice(totalCents: number, tenantId: string) {
return Buffer.from(`${tenantId}:${totalCents}`);
}
typescript
// server middleware — one enter per request
app.use((req, res, next) => {
reqAls.run(
{ reqId: req.headers["x-request-id"] as string ?? crypto.randomUUID(),
tenantId: String(req.headers["x-tenant-id"] ?? "") },
() => next(),
);
});
Hybrid for high-QPS gateways
| Layer | Carrier |
|---|---|
| Edge auth / HTTP middleware | ALS OK |
| ORM / HTTP client wrappers | read ALS once, pass explicit |
| Pure compute / codecs | explicit args only |
| Worker threads | structured clone of ctx snapshot |
Closing checklist
✅ Dos – ✅ Bench ALS on your Node version and hardware – ✅ Single store for request correlation – ✅ Explicit args on ultra-hot pure functions – ✅ Snapshot ctx when crossing into worker threads – ✅ KeepgetStore() off the per-byte codec path
❌ Don’ts
– ❌ Don’t nest a new ALS per dependency
– ❌ Don’t ban ALS globally without numbers
– ❌ Don’t forget lost context across poorly promisified callbacks
– ❌ Don’t store huge objects in ALS (retainers → heap pressure)
Related reading
- Node.js Event Loop Lag p99
- OpenTelemetry for LLMs
- Lambda Powertools Node Structured Logs
- Deterministic Replay: Agent Sessions
Watch: 100 Days of AI on YouTube
Short videos from CheatCoders, one AI engineering topic per day.
Most viewed
- Python Decorators Explained: From Simple Wrappers to Production Patterns
- Claude Code vs Cursor vs GitHub Copilot: Choose by Workflow, and Set Up One Repo That Works With All Three
- AI Agent Frameworks in 2025: LangGraph vs CrewAI vs AutoGen vs Raw API
- Python String Methods: Every str Method With Real Production Examples
- Css Animation Performance: Performance-Optimized Motion for Modern UIs
Newly added
- AWS Systems Manager Parameter Store: Hierarchical Runtime Config for Coding Agents
- Amazon Cognito Identity Pools: Federate Coding-Agent Tool Callers Without Long-Lived Keys
- Amazon Athena for Coding Agents: Query Tool Audit Logs and Eval Traces on S3 Without a Warehouse
- AWS Batch for Coding Agents: Parallel Overnight PR Reviews and Long-Running Jobs Without Lambda Timeouts
- Amazon Bedrock Prompt Management: Version and A/B Test Coding-Agent System Prompts
Deep-dive PDF
Get the expanded guide for this post — extra diagrams-style checklists, failure modes, and a production walkthrough. Free when you subscribe to CheatCoders.
Already subscribed? or open the subscribe page.
Discover more from CheatCoders
Subscribe to get the latest posts sent to your email.
