# Backend process handles graceful shutdown

- **Pattern:** `ab-001292` (`error-resilience.graceful-degradation-shutdown.graceful-shutdown`)
- **Severity:** low
- **Lifecycle:** active
- **Last modified:** 2026-04-18
- **Canonical URL:** https://auditbuffet.com/patterns/ab-001292
- **License:** CC-BY-4.0 — attribute to AuditBuffet Pattern Catalog (https://auditbuffet.com/patterns/ab-001292)

## Why it matters

A backend process that ignores SIGTERM drops in-flight requests immediately when the orchestrator (Kubernetes, Railway, Fly.io, Heroku) restarts or redeploys it. Users mid-checkout, mid-upload, or mid-auth flow receive hard errors with no recovery path. CWE-460 (improper cleanup on thrown exception) encompasses improper shutdown handling. Platforms send SIGTERM and wait a grace period (typically 30 seconds) before SIGKILL; failing to handle it means every deploy causes unannounced request failures that are invisible in your error tracking.

## Severity rationale

Low in environments with short-lived requests, but causes guaranteed data loss and user-facing errors on every deployment in applications with long-running operations.

## Remediation

Register SIGTERM and SIGINT handlers in your server entry point. Stop accepting new connections immediately, let in-flight requests finish, then close the database pool and exit.

```ts
// src/server.ts
const server = app.listen(3000)

async function shutdown(signal: string) {
  console.log(`${signal} received — shutting down`)
  server.close(async () => {
    await pool.end()
    process.exit(0)
  })
  // Force exit if drain takes too long
  setTimeout(() => process.exit(1), 30_000)
}

process.on('SIGTERM', () => shutdown('SIGTERM'))
process.on('SIGINT', () => shutdown('SIGINT'))
```

Test graceful shutdown locally: run your server, send `kill -SIGTERM <pid>`, and verify in-flight requests complete before the process exits.

## Detection

- **ID:** `graceful-shutdown`
- **Severity:** `low`
- **What to look for:** Count all signal handlers (SIGINT, SIGTERM) and cleanup routines. Enumerate whether the server completes in-flight requests and closes database connections before shutting down. Look for signal handlers (SIGTERM, SIGINT) in the backend entry point. Check whether the application waits for in-flight requests to complete and closes the connection pool before exiting.
- **Pass criteria:** Backend listens for SIGTERM and SIGINT; in-flight requests are completed before shutdown; connection pool is drained. At least 1 signal handler must be registered for SIGTERM with cleanup of at least 2 resources (DB connections, HTTP server).
- **Fail criteria:** No signal handlers configured, or shutdown immediately kills connections without draining.
- **Skip (N/A) when:** The application has no backend or is running in a serverless environment (AWS Lambda, Vercel Functions, etc.) that manages shutdown.

- **Cross-reference:** For database connection pool cleanup, see `database-connection-pool`.
- **Detail on fail:** `"No graceful shutdown handler. Server stops abruptly, killing in-flight requests"` or `"Signal handler exists but doesn't wait for requests to complete"`
- **Remediation:** Add graceful shutdown:

  ```ts
  // src/server.ts — graceful shutdown
  process.on('SIGTERM', async () => { await pool.end(); server.close(() => process.exit(0)) })
  ```

  ```ts
  // server.ts
  import express from 'express'
  import http from 'http'

  const app = express()
  const server = http.createServer(app)

  let isShuttingDown = false

  process.on('SIGTERM', () => {
    console.log('SIGTERM received, shutting down gracefully')
    isShuttingDown = true

    server.close(() => {
      console.log('Server closed')
      process.exit(0)
    })

    // Force exit after 30 seconds
    setTimeout(() => {
      console.error('Forced shutdown')
      process.exit(1)
    }, 30000)
  })

  server.listen(3000, () => {
    console.log('Server running')
  })
  ```

## External references

- cwe CWE-460
- iso-25010 reliability.recoverability

Taxons: error-resilience

HTML version: https://auditbuffet.com/patterns/ab-001292
