typescript 43 lines · 6 steps

Liveness vs readiness probes in NestJS

A NestJS health controller uses Terminus indicators to expose separate liveness and readiness endpoints.

Explained by highlit
1import { Controller, Get } from '@nestjs/common';
2import {
3 HealthCheck,
4 HealthCheckService,
5 TypeOrmHealthIndicator,
6 DiskHealthIndicator,
7 MemoryHealthIndicator,
8} from '@nestjs/terminus';
9import { ConfigService } from '@nestjs/config';
10 
11@Controller('health')
12export class HealthController {
13 constructor(
14 private readonly health: HealthCheckService,
15 private readonly db: TypeOrmHealthIndicator,
16 private readonly disk: DiskHealthIndicator,
17 private readonly memory: MemoryHealthIndicator,
18 private readonly config: ConfigService,
19 ) {}
20 
21 @Get('liveness')
22 @HealthCheck()
23 checkLiveness() {
24 return this.health.check([
25 () => this.memory.checkHeap('memory_heap', 300 * 1024 * 1024),
26 ]);
27 }
28 
29 @Get('readiness')
30 @HealthCheck()
31 checkReadiness() {
32 const path = this.config.get<string>('DISK_HEALTH_PATH', '/');
33 
34 return this.health.check([
35 () => this.db.pingCheck('database', { timeout: 1500 }),
36 () =>
37 this.disk.checkStorage('storage', {
38 path,
39 thresholdPercent: 0.9,
40 }),
41 ]);
42 }
43}
01 / 01
STEP 01

Walkthrough

Space play step click any line
Three takeaways
  1. 1Liveness should stay cheap and self-contained while readiness verifies external dependencies you rely on.
  2. 2Passing indicator checks as arrow functions lets the health service run and aggregate them lazily.
  3. 3Separating the two probes lets orchestrators restart a hung process without pulling a busy one out of rotation.

Related explainers

typescript
import { registerLocaleData } from '@angular/common';
import localeFr from '@angular/common/locales/fr';
import localeFrExtra from '@angular/common/locales/extra/fr';
import localeDe from '@angular/common/locales/de';

Locale-aware bootstrapping in Angular

i18n localization dependency-injection
Intermediate 8 steps
typescript
import { Module } from '@nestjs/common';
import { ConfigModule } from '@nestjs/config';
import * as Joi from 'joi';
 

Validating env config at boot in NestJS

configuration schema-validation environment-variables
Intermediate 8 steps
java
@Component
@Converter
public class EncryptedStringConverter implements AttributeConverter<String, String> {
 

Transparent column encryption in Spring & JPA

encryption aes-gcm jpa-converter
Advanced 10 steps
python
import time
import uuid
 
from django.utils.deprecation import MiddlewareMixin

Attaching per-request context in Django

middleware request lifecycle multi-tenancy
Intermediate 7 steps
typescript
import { Inject, Injectable, Logger } from '@nestjs/common';
import { CACHE_MANAGER } from '@nestjs/cache-manager';
import { Cache } from 'cache-manager';
import { InjectRepository } from '@nestjs/typeorm';

A cache-aside country lookup in NestJS

cache-aside dependency-injection batch-lookup
Intermediate 8 steps
java
package com.acme.billing.config;
 
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.ConfigurationProperties;

Feature-flagged beans with Spring @ConditionalOnProperty

feature-flags conditional-beans strategy-pattern
Intermediate 5 steps

Share this explainer

Here's the card — post it anywhere.

Liveness vs readiness probes in NestJS — share card
Made with highlit — turn any snippet into a walkthrough like this in about a minute.
Explain your code