Skip to content
Back to skills

Health Checks

ASecurity

Health check and graceful shutdown patterns. Liveness and readiness probes, dependency health checks, Kubernetes probes, Spring Actuator health, and zero-downtime shutdown. USE WHEN: user mentions "health check", "liveness", "readiness", "probe", "graceful shutdown", "SIGTERM", "health endpoint", "/healthz" DO NOT USE FOR: monitoring dashboards - use `error-tracking` or `opentelemetry`; deployment strategies - use `deployment-strategies`

  • 31 stars
  • 0 votes
  • 0 copies
  • 1 view
  • Added September 8, 2026
ai-agentstypescriptnodeexpressspringkubernetesapidatabase

Works with

  • api

Security analysis

A100/100

Scanned September 8, 2026

npx -y skills add claude-dev-suite/claude-dev-suite --skill health-checks --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Health Checks?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Health Checks
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/claude-dev-suite-health-checks/badge)](https://www.skillsdirectory.com/skills/claude-dev-suite-health-checks)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: health-checks
description: |
  Health check and graceful shutdown patterns. Liveness and readiness probes,
  dependency health checks, Kubernetes probes, Spring Actuator health,
  and zero-downtime shutdown.

  USE WHEN: user mentions "health check", "liveness", "readiness", "probe",
  "graceful shutdown", "SIGTERM", "health endpoint", "/healthz"

  DO NOT USE FOR: monitoring dashboards - use `error-tracking` or `opentelemetry`;
  deployment strategies - use `deployment-strategies`
allowed-tools: Read, Grep, Glob, Write, Edit
---
# Health Checks & Graceful Shutdown

## Health Check Endpoint (Express)

```typescript
app.get('/health/live', (req, res) => {
  res.json({ status: 'ok' }); // App process is running
});

app.get('/health/ready', async (req, res) => {
  const checks = await Promise.allSettled([
    checkDatabase(),
    checkRedis(),
    checkExternalApi(),
  ]);

  const results = checks.map((c, i) => ({
    name: ['database', 'redis', 'external-api'][i],
    status: c.status === 'fulfilled' ? 'up' : 'down',
    ...(c.status === 'rejected' && { error: c.reason.message }),
  }));

  const allHealthy = results.every((r) => r.status === 'up');
  res.status(allHealthy ? 200 : 503).json({ status: allHealthy ? 'ready' : 'degraded', checks: results });
});

async function checkDatabase() {
  await db.$queryRaw`SELECT 1`;
}
async function checkRedis() {
  await redis.ping();
}
```

## Graceful Shutdown (Node.js)

```typescript
const server = app.listen(3000);

async function shutdown(signal: string) {
  console.log(`${signal} received, starting graceful shutdown`);

  // 1. Stop accepting new connections
  server.close();

  // 2. Wait for in-flight requests (with timeout)
  const timeout = setTimeout(() => process.exit(1), 30000);

  try {
    // 3. Close dependencies
    await db.$disconnect();
    await redis.quit();
    await queue.close();
    clearTimeout(timeout);
    process.exit(0);
  } catch {
    process.exit(1);
  }
}

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

## Kubernetes Probes

```yaml
containers:
  - name: app
    livenessProbe:
      httpGet: { path: /health/live, port: 3000 }
      initialDelaySeconds: 10
      periodSeconds: 15
      failureThreshold: 3
    readinessProbe:
      httpGet: { path: /health/ready, port: 3000 }
      initialDelaySeconds: 5
      periodSeconds: 10
      failureThreshold: 2
    startupProbe:
      httpGet: { path: /health/live, port: 3000 }
      failureThreshold: 30
      periodSeconds: 2
    lifecycle:
      preStop:
        exec:
          command: ["sh", "-c", "sleep 5"]  # Allow LB to drain
```

## Spring Boot Actuator

```yaml
management:
  endpoints:
    web:
      exposure:
        include: health,info
  endpoint:
    health:
      show-details: when_authorized
      group:
        readiness:
          include: db,redis,diskSpace
        liveness:
          include: ping
  health:
    redis:
      enabled: true
```

## Probe Types

| Probe | Purpose | Failure Action |
|-------|---------|---------------|
| **Liveness** | Is the process alive? | Restart container |
| **Readiness** | Can it serve traffic? | Remove from load balancer |
| **Startup** | Has it finished initializing? | Don't check liveness yet |

## Anti-Patterns

| Anti-Pattern | Fix |
|--------------|-----|
| Liveness check hits database | Liveness = process alive only; readiness = dependencies |
| No graceful shutdown | Handle SIGTERM, drain connections |
| Immediate process.exit() | Wait for in-flight requests to complete |
| No startup probe | Slow-starting apps killed by liveness before ready |
| Health check returns 200 when degraded | Return 503 when dependencies are down |

## Production Checklist

- [ ] Separate liveness and readiness endpoints
- [ ] Readiness checks all critical dependencies
- [ ] Graceful shutdown handles SIGTERM
- [ ] In-flight requests drained before exit
- [ ] Kubernetes probes configured with proper thresholds
- [ ] Startup probe for slow-initializing apps

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…

Newsletter

Get the weekly list of safe new skills, and the ones we pulled.