graceful-shutdown
Lets your agent implement safe server shutdowns, ensuring task completion.
What it does
This tool helps computer programs finish their tasks in an organized way. It ensures everything being worked on is completed before shutting down, preventing data loss or abrupt interruptions.
When to use it
- ✓When updating a program without it needing to suddenly stop working.
- ✓When a program processing tasks needs to end safely.
- ✓When using systems that send a signal to shut down the program politely.
Example of what to ask your AI
“How do I make my program shut down safely when it receives a shutdown signal?”
Want more? Open the sections below.
How to use
The easiest way: copy the message below and paste it into Claude, ChatGPT, Cursor or any AI. It reads the skill and follows the instructions.
Skill link
Ready-to-paste message
How it works
The program listens for shutdown signals (like Ctrl+C). Upon receiving one, it stops accepting new tasks, waits for current tasks to finish, and releases resources before exiting.
Installation
Easiest way: copy the skill link and paste it into Claude, ChatGPT or Cursor asking it to follow the instructions.
In the terminal (Claude Code, Codex, Cursor), in your project folder:
npx skills add sickn33/agentic-awesome-skills --skill graceful-shutdownOr download just the file:
curl -L https://raw.githubusercontent.com/sickn33/agentic-awesome-skills/main/plugins/agentic-awesome-skills-claude/skills/graceful-shutdown/SKILL.md -o SKILL.mdTechnical content (original SKILL.md)
Original text by the author, straight from GitHub.
Graceful Shutdown
Overview
A skill for implementing graceful shutdown in servers, workers, and long-running processes. Ensures in-flight requests complete, background jobs finish or checkpoint, database connections close cleanly, and the process exits with a proper status code. Essential for zero-downtime deployments in container orchestrators (Kubernetes, ECS, Docker Compose) and bare-metal process managers (systemd, PM2).
When to Use This Skill
- Use when building an HTTP server that must not drop active connections during deploys
- Use when writing a background worker that processes jobs from a queue
- Use when deploying to Kubernetes, Docker, or any environment that sends SIGTERM before killing
- Use when the user says "graceful shutdown", "drain connections", "handle SIGTERM", "zero downtime", or "don't kill active requests"
- Use when implementing health check endpoints (
/healthz,/readyz) for orchestrators
How It Works
Step 1: Register signal handlers early
Trap SIGTERM (orchestrator shutdown) and SIGINT (Ctrl+C) at process startup. Set a flag so the application knows it is shutting down.
let isShuttingDown = false;
function onShutdownSignal(signal: string): void {
if (isShuttingDown) return; // prevent double-shutdown
isShuttingDown = true;
console.log(`Received ${signal}, starting graceful shutdown...`);
shutdown();
}
process.on("SIGTERM", () => onShutdownSignal("SIGTERM"));
process.on("SIGINT", () => onShutdownSignal("SIGINT"));
Step 2: Stop accepting new work
Immediately stop the server from accepting new connections. For HTTP servers, call server.close(). For queue workers, stop polling for new jobs.
async function shutdown(): Promise<void> {
// 1. Stop accepting new connections
server.close(() => {
console.log("Server closed — no new connections accepted");
});
// 2. Mark health check as not-ready so load balancers stop routing
// (readiness probe returns 503 from this point)
}
Step 3: Drain in-flight work with a deadline
Wait for active requests and background tasks to finish, but enforce a hard deadline so the process never hangs indefinitely.
const DRAIN_TIMEOUT_MS = 25_000; // must be less than orchestrator's terminationGracePeriodSeconds
async function drainAndExit(): Promise<void> {
const deadline = setTimeout(() => {
console.error("Drain timeout reached — forcing exit");
process.exit(1);
}, DRAIN_TIMEOUT_MS);
deadline.unref(); // don't keep the event loop alive just for the timer
try {
// Wait for active connections to finish
await waitForActiveConnections();
// Flush buffered data (logs, metrics, queues)
await flushBuffers();
// Close external resource handles
await closeResources();
console.log("Graceful shutdown complete");
process.exit(0);
} catch (err) {
console.error("Error during shutdown:", err);
process.exit(1);
}
}
Step 4: Implement readiness and liveness probes
Orchestrators use these to decide whether to route traffic and whether to restart the container. Liveness proves the process is alive; readiness controls whether traffic is routed. While the listener is still available during a drain, keep liveness healthy and return 503 only from readiness. After the listener closes, new probes cannot connect, so do not promise that HTTP liveness remains reachable for the entire termination window.
import { createServer, IncomingMessage, ServerResponse } from "node:http";
function handleHealthCheck(req: IncomingMessage, res: ServerResponse): void {
if (req.url === "/healthz") {
// Keep liveness distinct from readiness while the listener is available.
// Drain-rejection middleware must not turn this endpoint into a 503.
res.writeHead(200).end("ok");
return;
}
if (req.url === "/readyz") {
// Readiness: 503 during shutdown so the load balancer stops routing.
if (isShuttingDown) {
res.writeHead(503).end("shutting down");
} else {
res.writeHead(200).end("ready");
}
return;
}
}
Step 5: Track active connections
Maintain a count of in-flight requests so you know when draining is complete. Use a once guard covering both finish and close events so that client disconnects (aborted requests) correctly decrement the counter.
let activeConnections = 0;
let drainResolve: (() => void) | null = null;
…
FAQ
Why is 'graceful shutdown' important?
To avoid losing data, corrupting files, or interrupting users in the middle of an operation. It ensures a smooth transition, especially in automated systems.
What happens if I don't use this tool?
The program might be terminated abruptly, cutting off connections and leaving tasks unfinished. This can cause errors, data loss, and problems in systems that depend on it.
Does this tool work for any type of program?
Yes, it's designed for servers, background processes (workers), and any program that requires a controlled and safe termination.
Details
Original description by the author
Implement graceful shutdown for servers and workers: drain connections, finish in-flight work, release resources, and exit cleanly on SIGTERM/SIGINT.
Popularity
- GitHub stars
- 48k
- Ranking position
- #3166
- License
- MIT
- Updated
- 10/15/2026
Comments
- …
More skills from this repository
00-andruia-consultant
Helps your agent start or improve AI projects. It analyzes code, suggests tools, and creates action plans in Spanish.
sickn33/agentic-awesome-skills
007
Lets your agent perform security audits and threat modeling. It's useful for protecting projects against attacks and vulnerabilities.
sickn33/agentic-awesome-skills
10-andruia-skill-smith
Helps your agent create or improve AI tools. It defines how tools work, writes documentation, and validates the structure.
sickn33/agentic-awesome-skills
20-andruia-niche-intelligence
Lets your agent create a summary about a specific industry. It's useful for understanding the context, rules, usage patterns, and risks of a project, using reliable sources.
sickn33/agentic-awesome-skills
Similar skills
bun-runtime
Has your agent use Bun to run, organize, and test code. It helps choose Bun over other tools and migrate existing projects.
affaan-m/ECC
database-migrations
Helps your agent make safe changes to databases. It ensures changes can be undone and minimizes downtime.
affaan-m/ECC
deployment-patterns
Sets up deployment and CI/CD workflows, containerization, and rollback strategies to ensure safe releases.
affaan-m/ECC