SyncTrix logoSyncTrix
All articles
Platform10 min read

Why your deploys drop requests: graceful shutdown in Kubernetes

Rolling deploys are supposed to be zero-downtime and frequently are not. The cause is almost always shutdown ordering, not capacity.

By Marcus Hale
Why your deploys drop requests: graceful shutdown in Kubernetes

A rolling deploy produces a small spike of 502s. Nobody investigates because it is brief, it is only during deploys, and the dashboards recover. It is worth investigating, because the cause is a race between two systems that do not coordinate, and it is entirely fixable.

01The race that causes it

When a pod is terminated, two things happen concurrently: the container receives SIGTERM, and endpoint removal begins propagating so load balancers stop routing to it. These are independent processes with no ordering guarantee.

If your application exits promptly on SIGTERM, it can be gone before the propagation completes - and requests routed in that window hit nothing. The application did what it was told; the routing had not caught up.

02The fix is to wait before exiting

The counterintuitive answer is that on SIGTERM your application should keep serving for a short period rather than shutting down immediately. That window lets endpoint removal propagate, so by the time you stop accepting connections nothing is being routed to you.

A preStop hook that sleeps for a few seconds achieves this without application changes, which makes it the pragmatic first fix. The right duration depends on how quickly your ingress and service mesh converge - measure it rather than guessing, but a handful of seconds is typical.

03The shutdown sequence that works

Order matters, and each step exists for a reason. Fail readiness first so nothing new is routed, keep serving for the propagation window, then stop accepting new connections while letting in-flight requests finish, then close dependencies and exit.

StepActionWhy
1Fail the readiness probeStops new traffic being routed
2Keep serving for a few secondsLets endpoint removal propagate
3Stop accepting new connectionsIn-flight requests continue
4Drain in-flight workNo request is cut mid-response
5Close database and queue connectionsAvoids leaked connections
6Exit before the grace period endsPrevents SIGKILL mid-work
Correct shutdown ordering

04The grace period must exceed your longest request

Kubernetes waits for the termination grace period, then sends SIGKILL regardless of what is happening. If a request takes longer than that period, it is severed mid-flight - and the client sees a connection reset rather than an error it can interpret.

Set the grace period above your longest realistic request or background job, including the propagation wait at the start. Long-running jobs need particular attention: they either need to complete within the window or be designed to resume, and discovering which during an incident is unpleasant.

  • Grace period > propagation wait + longest request duration.
  • Background workers need resumability or bounded runtime.
  • Verify the process actually exits before SIGKILL fires.
  • Log shutdown steps so you can confirm ordering in production.

05Signals that do not reach your process

A container whose entrypoint is a shell script often has that shell as process one, and it may not forward SIGTERM to the application. The application then never begins shutting down and is killed at the end of the grace period every time.

The symptom is that shutdown always takes exactly the grace period. If deploys consistently take that long, check what process one actually is - using exec form for the entrypoint or a minimal init process usually resolves it immediately.

06Verifying it works

Run a steady stream of requests during a rolling deploy and count non-200 responses. This is the only test that matters, because reading the configuration cannot tell you whether propagation timing on your cluster is what you assumed.

Do it after any change to ingress, service mesh or shutdown handling. The window is timing-dependent, so a configuration that works today can start dropping requests after an unrelated infrastructure change.

Topics

kubernetes graceful shutdownzero downtime deploymentsigterm handlingkubernetes dropped connectionsprestop hookrolling update errors

Marcus Hale

Lead Architect · SyncTrix

Writes about the engineering decisions behind production systems - architecture, delivery and the trade-offs that only show up at scale.

Building something like this?

SyncTrix engineers AI, SaaS, platform and cloud systems for enterprises and high-growth teams. Tell us what you're shipping and we'll scope it with you.