Health checks with Terminus
Tags: nestjs, terminus
Published: 2023-04-14 14:00:01

---
title: Health checks with Terminus
published: true
tags: ['nestjs', 'terminus']
canonical_url: https://sevic.dev/notes/healthcheck-terminus-nestjs/
---

Monitoring tools use health checks to check if service and external dependencies (like a database) are up and running and take some action (like sending alerts) for the unhealthy state.

Terminus provides a set of health indicators.

### Liveness probe

An HTTP endpoint checks if the service is up and running.

```ts
// health.controller.ts
import { Controller, Get } from '@nestjs/common';
import { ApiTags } from '@nestjs/swagger';
import {
  HealthCheck,
  HealthCheckResult,
  HealthCheckService,
  HealthIndicatorResult,
  TypeOrmHealthIndicator
} from '@nestjs/terminus';
import { CustomConfigService } from 'common/config/custom-config.service';

@ApiTags('health')
@Controller('health')
export class HealthController {
  constructor(
    private readonly healthCheckService: HealthCheckService,
    private readonly configService: CustomConfigService,
    private readonly database: TypeOrmHealthIndicator
  ) {}

  @Get('liveness')
  @HealthCheck()
  async check(): Promise<HealthCheckResult> {
    return this.healthCheckService.check([
      async (): Promise<HealthIndicatorResult> => ({
        [this.configService.SERVICE_NAME]: { status: 'up' }
      })
    ]);
  }
  // ...
}
```

A successful response is like the one below.

```json
{
  "status": "ok",
  "info": {
    "nestjs-starter": {
      "status": "up"
    }
  },
  "error": {},
  "details": {
    "nestjs-starter": {
      "status": "up"
    }
  }
}
```

### Readiness probe

An HTTP endpoint checks if the service is ready to receive the traffic and if all external dependencies are running.

```ts
// health.controller.ts
import { Controller, Get } from '@nestjs/common';
import { ApiTags } from '@nestjs/swagger';
import {
  HealthCheck,
  HealthCheckResult,
  HealthCheckService,
  HealthIndicatorResult,
  TypeOrmHealthIndicator
} from '@nestjs/terminus';
import { CustomConfigService } from 'common/config/custom-config.service';

@ApiTags('health')
@Controller('health')
export class HealthController {
  constructor(
    private readonly healthCheckService: HealthCheckService,
    private readonly configService: CustomConfigService,
    private readonly database: TypeOrmHealthIndicator
  ) {}

  // ...
  @Get('readiness')
  @HealthCheck()
  async checkReadiness(): Promise<HealthCheckResult> {
    return this.healthCheckService.check([
      async (): Promise<HealthIndicatorResult> =>
        this.database.pingCheck('postgres')
    ]);
  }
}
```

#### Responses

- Successful response

```json
{
  "status": "ok",
  "info": {
    "postgres": {
      "status": "up"
    }
  },
  "error": {},
  "details": {
    "postgres": {
      "status": "up"
    }
  }
}
```

- Response when the database is down

```json
{
  "status": "error",
  "info": {},
  "error": {
    "postgres": {
      "status": "down"
    }
  },
  "details": {
    "postgres": {
      "status": "down"
    }
  }
}
```

### Demo

The demo with the mentioned examples is available [here](https://sevic.dev/demos).