Does AsyncLocalStorage avoid the latency cost of request-scoped providers in NestJS? It can avoid creating request-lifetime provider instances when all you need is to carry values such as a request ID, user, tenant, or locale through asynchronous work. That is a useful architectural distinction, not proof of a universal speedup: NestJS gives approximate guidance for request scope, but the sources here do not establish a general head-to-head performance ratio.
What changes: provider lifetime or context propagation?
These approaches solve related but different problems. A provider’s scope determines when NestJS creates its instances. AsyncLocalStorage (ALS) associates data with an asynchronous execution path so downstream code can retrieve it. If a service needs a different instance for every request, changing how context is stored does not remove that requirement. If the service is otherwise reusable and only needs request-specific values, context propagation may let it remain a singleton.
As an Amazon Associate I earn from qualifying purchases.
| Question | Request-scoped providers | AsyncLocalStorage context |
|---|---|---|
| What varies? | Provider instances: NestJS creates an instance for each incoming request. | Context data: values are associated with an asynchronous execution. |
| How does downstream code access it? | Through injected request/context dependencies, such as REQUEST or GraphQL CONTEXT. |
By reading the store established at an appropriate request, message, or job boundary. |
| What happens to the dependency graph? | Request scope bubbles up: consumers that depend on a request-scoped provider also become request-scoped. | Providers can remain singleton-scoped while reading execution-specific values. |
| Where does the approach fit? | When construction lifetime itself must vary by request, or a provider needs the request object. | When shared services need cross-cutting context but not per-request instances. |
| What performance conclusion is supported? | NestJS warns that per-request instantiation affects performance and gives an approximate expectation for properly designed use. | It can avoid request-scoped provider construction for context-only needs; no universal comparative latency figure is established. |
Node.js describes ALS as a stable API for associating and propagating state through callbacks and promise chains. It became stable in Node.js v16.4.0; the cited API documentation is for Node.js v26.10.0. See Node.js asynchronous context tracking.
Why request scope can affect latency
NestJS has three provider scopes. DEFAULT is singleton and is the default; REQUEST creates a provider instance for each incoming request; and TRANSIENT gives each consumer its own provider instance. With request scope, a request-scoped dependency can make its upstream consumers request-scoped too. A single request-specific leaf can therefore change how much of the provider graph is instantiated per request.
#1 Best Overall
NestJS warns that these per-request instantiations affect performance and recommends singleton scope unless request scope is needed. Its 2026 documentation says: “A properly designed application that uses request-scoped providers should not see latency increase by more than ~5%.” Treat that as framework guidance and an approximate expectation—not a guarantee, a result for every application, or an AsyncLocalStorage-versus-DI benchmark. Read the current NestJS injection-scope documentation for the framework’s scope semantics and guidance.
When AsyncLocalStorage is the better fit
Use ALS when a value belongs to the current execution but the services handling that execution do not need different construction or mutable instance state. Common examples include carrying a request ID for logs, or making authenticated-user, tenant, or locale context available across downstream asynchronous code. The key benefit is keeping those services singleton-scoped rather than promoting them to request scope solely to reach context.
NestJS documents this pattern across HTTP handlers, microservice message handlers, and queue jobs. Establish the context at the appropriate boundary, then access it only within work that remains on that asynchronous execution path. ALS propagates through callbacks and promise chains; it is not a replacement for dependency injection or a mechanism for making all arbitrary work share the same context.
The Tool Desk
Outbyte PC Repair FREEClear out junk files and repair common Windows errorsFree Scan →Outbyte Driver Updater FREEScan for outdated or missing drivers - takes under a minuteDriver Scan →- Request ID or tracing metadata: usually context data, not a reason to construct an entire request-specific service graph.
- User, tenant, or locale: often context values if services only read them while handling the current execution.
- Request-bound state or construction: request scope may still be appropriate when the provider genuinely needs a request-lifetime instance or injected request object.
When request-scoped providers remain appropriate
Choose request scope when the provider’s lifetime or state truly belongs to one request, rather than using it merely as a convenient channel for a few values. NestJS’s REQUEST provider is inherently request-scoped; a provider that depends on it adopts request scope as well. The documented GraphQL equivalent uses CONTEXT.
Rank #3
Some NestJS components should remain singleton-scoped: the documentation warns against request scope for WebSocket gateways, which need to be singletons, and identifies Passport strategies and Cron controllers as examples that should remain singleton. These are framework lifecycle constraints, not merely performance preferences.
Multi-tenant applications: a separate lifetime option
For multi-tenant architectures, NestJS also documents durable providers and grouped DI subtrees. This is distinct from ALS: it can reuse a dependency-injection subtree based on a stable tenant attribute instead of creating the same subtree for every request. NestJS cautions that this strategy is not ideal when there are a large number of tenants. Use it when tenant-based provider reuse is the actual design need, not just to propagate a tenant ID to otherwise shared services.
Rank #4
How to choose and validate the design
- Identify the requirement. Ask whether the provider must be instantiated per request, or whether it only needs access to values associated with the current execution.
- Keep ordinary services singleton-scoped. If only context values vary, establish and read ALS context rather than introducing request scope solely for access.
- Reserve request scope for request-lifetime behavior. Check the full dependency chain: a request-scoped dependency can make its consumers request-scoped too.
- Benchmark the actual application if latency matters. Compare the same workload and dependency graph, with consistent Node.js and framework versions, hardware, request complexity, concurrency, warmup, and measured metrics. Do not infer your result from a different application’s numbers.
A project-maintained benchmark in the pas7-studio nestjs-request-context repository reports measurements for Node.js v24.6.0 on its named local CPU and workload, last measured February 14, 2026. It warns that results vary with Node version, hardware, request complexity, and DI graph depth. Those figures are workload-specific and self-reported, not independent validation or a general NestJS performance ratio.
Quick Recap
Best Value
Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.




