Graceful Shutdown in NestJS: Ensuring Smooth Application Termination
Tags: nestjs, node, typescript, javascript
Published: 2023-09-01 08:28:18

A graceful shutdown is the process of shutting down a web application in a controlled and orderly manner, ensuring that all processes are safely terminated and all connections are closed. This is important for web applications as it helps to prevent data loss and corruption, and ensures that users are not left with incomplete or failed requests. In this blog post, we'll delve into the concept of graceful shutdown and learn how to implement it in a NestJS application.

Let's get started! 🐈

## Why We Need Graceful Shutdown for the Server

Graceful shutdown is essential in scenarios like:

- **Deploying New Version**: Ensure data integrity and user experience during version updates.

- **Scaling Operations**: Avoid data inconsistencies when scaling up or down.

- **Zero Downtime**: Maintain availability during updates.

- **Resource Cleanup**: Properly release resources before shutdown.

- **Long-Running Processes**: Allow ongoing tasks to complete before shutdown.

- **Background Tasks**: Ensure background processes finish properly.

- **Server Failure**: Handle shutdown during server failures to prevent data loss.

- **Enhancing User Experience**: Maintain reliability and trust for users.

## Implementing Graceful Shutdown for NestJS Application

To achieve a graceful shutdown in your application, you'll need to capture the shutdown signal and create a function that responds to it by performing tasks such as halting new requests, completing ongoing requests or tasks, and cleaning up resources. In the context of NestJS, you can utilize the `enableShutdownHooks()` method along with lifecycle events like `onModuleDestroy`, `beforeApplicationShutdown`, and `onApplicationShutdown` to handle the shutdown sequence effectively. These mechanisms allow you to respond to specific shutdown signals and execute actions like closing database connections and releasing resources as the application shuts down.

Here's a guide on how to implement this:

Consider the following code:

```typescript
import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';

async function bootstrap() {
  const app = await NestFactory.create(AppModule);
  app.enableShutdownHooks(); // Enable listening for shutdown hooks

  await app.listen(3000);

  // For illustration purposes, delay the shutdown
  setTimeout(() => {
    process.kill(process.pid, 'SIGTERM');
  }, 5000);
}
bootstrap();

```
If you have implemented a graceful shutdown for a NodeJS application or a specific NodeJS framework like ExpressJS, you may have noticed that you need to call the `server.close()` method from the native Node Server Instance to stop the server from accepting new connections while maintaining existing ones. However, It might lead to server hang indefinitely due to lingering `keep-alive` connections or unresponsive requests. This issue can also occur in NestJS applications using the `enableShutdownHooks()` method. To properly close the server, you must track the creation of all connections and terminate them yourself. To achieve this, you can use the `nestjs-graceful-shutdown` package available at [npm](https://www.npmjs.com/package/nestjs-graceful-shutdown), which simplifies the graceful shutdown process for your NestJS application.

Here's how you can integrate it:

- Import the module into your root `AppModule`:

```typescript
import { GracefulShutdownModule } from 'nestjs-graceful-shutdown';

@Module({
  imports: [
    GracefulShutdownModule.forRoot({
      cleanup: async (app) => {
        // releasing resources
        const myService = app.get(MyService);
        await myService.close();
      },
    })
  ],
  ...
})
class AppModule {}
```
- Set up graceful shutdown by calling the `setupGracefulShutdown(...)` function:

```typescript
import { setupGracefulShutdown } from 'nestjs-graceful-shutdown';
import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';

async function bootstrap() {
  const app = await NestFactory.create(AppModule);
  // Additional configuration for your NestJS app

  setupGracefulShutdown({ app });

  await app.listen(3000);

  // For illustration purposes, delay the shutdown
  setTimeout(() => {
    process.kill(process.pid, 'SIGTERM');
  }, 5000);
}
bootstrap();
```

The `nestjs-graceful-shutdown` package also offers configuration options to manage resource cleanup before shutting down the server. Refer to the [documentation](https://www.npmjs.com/package/nestjs-graceful-shutdown) for more details.

## Conclusion

In conclusion, implementing a graceful shutdown in NestJS is crucial for ensuring a controlled and orderly shutdown process. By following these steps and utilizing the `nestjs-graceful-shutdown` package, you can seamlessly manage shutdown events and prevent disruptions during the shutdown process.

Happy hacking! 🐈