Lifecycle Hooks: OnModuleInit, OnApplicationBootstrap, and Graceful Shutdown
- Last updated
- Prerequisites:
- NestJS ApplicationContext
- Node.js process signals (SIGTERM, SIGINT)
- nestjs
- lifecycle
- onModuleInit
- onApplicationBootstrap
- shutdown-hooks
- graceful-shutdown
Read at your depth
The practical view
NestJS providers and modules can hook into application startup and shutdown events by implementing lifecycle interfaces: `OnModuleInit` (called immediately after module dependencies resolve), `OnApplicationBootstrap` (called right before the app starts listening), `BeforeApplicationShutdown` (called when SIGTERM is received), and `OnApplicationShutdown` (called after connections close). To enable shutdown hooks, call `app.enableShutdownHooks()`.
The same idea in other frameworks
`implements OnModuleInit, OnApplicationShutdown` with `app.enableShutdownHooks()`.Spring `@PostConstruct`, `InitializingBean`, `@PreDestroy`, and `DisposableBean`.FastAPI `@asynccontextmanager` lifespan events (`yield` for startup/shutdown).`process.on('SIGTERM', async () => { await db.close(); process.exit(0); })`.Legacy vs modern
Ad-hoc Process Signal Handlers vs Native NestJS Lifecycle Hooks
Manual `process.on('SIGTERM')` handlers create race conditions with the HTTP server; NestJS lifecycle hooks ensure clean drained shutdowns.
process.on('SIGTERM', () => db.disconnect()); // ❌ Drops in-flight requests and causes race conditionsexport class DatabaseService implements OnModuleInit, OnApplicationShutdown { ... } // ✅ NEWInterview gotchas
Context
Interviewers test your real-world production deployment experience on Kubernetes / Docker.
The mechanical answer
By default, NestJS **does not enable system signal listeners** to save memory and avoid unintended process exits. You **must explicitly call `app.enableShutdownHooks()`** in `main.ts` before `app.listen()`. Without calling `enableShutdownHooks()`, receiving a `SIGTERM` signal (e.g. from Kubernetes during pod termination) will terminate the Node.js process immediately without running any `onApplicationShutdown` or `beforeApplicationShutdown` hooks.
Trap
Always call `app.enableShutdownHooks()` in production entrypoints to prevent database connection drop corruption during rolling deploys.
Context
Checks knowledge of initialization phases in the NestJS container.
The mechanical answer
`onModuleInit()` runs for each module as soon as its individual dependencies are resolved (can be called while other sibling modules are still initializing). `onApplicationBootstrap()` runs **only after ALL modules in the entire application have finished their `onModuleInit`**, guaranteeing that all services across the entire dependency graph are fully ready.
Trap
Do not call cross-module dependent initialization logic in `onModuleInit()`; use `onApplicationBootstrap()` to ensure cross-module dependencies are initialized.