Transient Scope
⭐ Interview Importance: HIGH
⏱️ Revision Time: 6 min
The Transient Scope (Scope.TRANSIENT) tells NestJS to create a new, dedicated instance of the provider every time it is injected.
Overview
Transient scope is unique because it doesn’t map to the application lifecycle (like Singleton) or the HTTP request lifecycle (like Request).
Instead, it maps to the injection point. If three different services inject a TransientScopedService, Nest will instantiate three completely separate copies of TransientScopedService and give one to each consumer.
Key Concepts
Scope.TRANSIENT: The enum value used to define this scope.- No Sharing: State is absolutely never shared between consumers.
- No Bubbling Effect: Unlike Request Scope, injecting a Transient provider does not force the consumer to become Transient. If a Singleton controller injects a Transient service, the controller remains a Singleton (and it holds onto its unique instance of the Transient service forever).
Code Examples
Defining a Transient Provider
import { Injectable, Scope } from '@nestjs/common';
@Injectable({ scope: Scope.TRANSIENT })
export class LoggerService {
private context: string;
setContext(context: string) {
this.context = context;
}
log(message: string) {
console.log(`[${this.context}] ${message}`);
}
}
Injecting into Consumers
Because LoggerService is transient, UsersService and OrdersService each get their own private instance. They can safely call setContext() without overwriting each other!
import { Injectable } from '@nestjs/common';
import { LoggerService } from './logger.service';
@Injectable()
export class UsersService {
constructor(private logger: LoggerService) {
// This only affects the UsersService's private copy of LoggerService
this.logger.setContext('UsersService');
}
create() {
this.logger.log('Creating user...'); // Output: [UsersService] Creating user...
}
}
import { Injectable } from '@nestjs/common';
import { LoggerService } from './logger.service';
@Injectable()
export class OrdersService {
constructor(private logger: LoggerService) {
// This only affects the OrdersService's private copy
this.logger.setContext('OrdersService');
}
create() {
this.logger.log('Creating order...'); // Output: [OrdersService] Creating order...
}
}
Best Practices
- Perfect for Loggers: The absolute most common (and arguably best) use case for
Scope.TRANSIENTis for custom Logger services. It allows every Singleton service in your app to inject the Logger, set its own class name as the “Context”, and log messages without interfering with other classes. - Be Careful with Connections: Do not use Transient scope for classes that establish network connections (like a database repository). You will end up opening hundreds of separate database connections, rapidly exhausting your connection pool.