Graceful shutdown

Without graceful shutdown wired, your server dies immediately on SIGTERM and in-flight requests are dropped. Every production deployment needs this. Ingenium ships gracefulShutdown(server, opts) to handle the lifecycle correctly.

Usage

import { ingenium, gracefulShutdown } from 'ingenium'

const app = ingenium()
const server = await app.listen(3000)

gracefulShutdown(server, {
  gracefulTimeoutMs: 10_000,                  // force-close idle keep-alives after 10s
  signals: ['SIGTERM', 'SIGINT'],
  onShutdown: async () => {
    await db.close()
    await queue.flush()
  },
})

Behavior

  • Listens for the configured signals (default: SIGTERM, SIGINT).
  • Stops accepting new connections.
  • Lets in-flight requests finish.
  • Force-closes idle keep-alive connections after gracefulTimeoutMs.
  • Runs onShutdown for your cleanup work (DB pools, queues, file handles).
  • A second signal during shutdown triggers an immediate exit(1) - the force-quit escape hatch when something is hung.

Why this matters

Container orchestrators (Kubernetes, ECS, Nomad) send SIGTERM before SIGKILL precisely so apps can drain. Without graceful shutdown, every deploy and every pod restart drops every in-flight request that was unlucky enough to be mid-flight. With it, drains are invisible to clients.

Wiring with the close API

server.close({ gracefulTimeoutMs }) is the lower-level primitive gracefulShutdown uses internally. If you want to drive shutdown from your own signal handlers or admin endpoint, call server.close(...) directly.

Where to next?