On this page
What Is Graceful Shutdown?
Graceful shutdown lets an app finish in-flight work before exiting instead of dropping requests mid-flight. Learn how it works and why deploys need it.
Quick answer
- Graceful shutdown means your app stops accepting new work, finishes what’s in flight, then exits.
- Without it, every deploy or restart kills in-progress requests, causing errors and lost work.
- You implement it by handling the termination signal, draining connections, and only then exiting.
What happens without graceful shutdown?
When a deploy or scale-down kills a process, the default behavior is an abrupt stop: connections drop, in-flight requests fail with network errors, and a request that was writing to a database may leave partial state. In a container, the orchestrator sends SIGTERM and then, after a grace period, SIGKILL. If your app ignores SIGTERM or exits immediately, you get the worst of both: either the kill is abrupt, or the grace period expires and the process is force-killed mid-work.
How do you implement it?
Listen for the termination signal, tell your server to stop accepting new connections, wait for in-flight requests to finish (with a timeout), then exit. Most frameworks have this built in or one line away. In Node, call server.close(); in Go, use a signal.NotifyContext and http.Server.Shutdown; Python frameworks vary. The example shows the Node pattern.
const server = app.listen(process.env.PORT || 3000);
async function shutdown(signal) {
console.log(`${signal} received, draining...`);
server.close(async () => {
await closeDbConnections();
process.exit(0);
});
// Force exit if draining takes too long (match your platform's grace period)
setTimeout(() => process.exit(1), 25_000).unref();
}
process.on("SIGTERM", () => shutdown("SIGTERM"));
process.on("SIGINT", () => shutdown("SIGINT"));Why does this matter for deploys specifically?
Deploys restart your process constantly. If each restart drops a handful of in-flight requests, users see random failures — and the load balancer only removes an instance from rotation after it stops passing health checks, so traffic can still arrive during the drain. Graceful shutdown plus a readiness endpoint that flips to not-ready during drain makes deploys invisible to users.
Where this bites vibecoders
AI assistants produce servers that handle requests beautifully and ignore shutdown entirely — the generated Express or FastAPI app exits instantly on SIGTERM, and the vibecoder blames ‘flaky deploys’ for errors that are actually dropped in-flight requests. The fix is small and mechanical, but it’s the kind of operational behavior an assistant won’t add unless you name it.
Where AI coding assistants get this wrong
- No signal handling at all, so processes are force-killed mid-request.
- Ignoring SIGTERM indefinitely, which guarantees the platform SIGKILLs the process.
- Closing the database before the server finishes in-flight requests.
- No drain timeout, so a stuck request blocks shutdown until the platform kills it.
Checklist
- Handle SIGTERM and SIGINT and drain in-flight requests before exiting.
- Set a drain timeout shorter than your platform’s grace period.
- Flip readiness to not-ready during shutdown so the load balancer stops routing.
- Test: deploy while traffic is flowing and watch for zero dropped requests.
FAQ
What’s the difference between SIGTERM and SIGKILL?
SIGTERM is a polite request to terminate — your app can catch it and clean up. SIGKILL can’t be caught or ignored; it force-kills the process immediately. Orchestrators send SIGTERM first, then SIGKILL after the grace period, which is why handling SIGTERM matters.
How long should my app take to shut down?
As long as in-flight requests genuinely take, capped well under your platform’s grace period (commonly 30 seconds). If requests routinely take longer than the grace period, that’s a request-length problem worth fixing separately.
Related topics
- Why Does My App Ignore SIGTERM (and How Do I Fix It)?
- What Is a Health Check?
- What Is Zero-Downtime Deployment?
- How to Roll Back a Bad Deploy
- How to Add Health Checks to Your App