πŸ“šBook Signing at KubeCon EU 2026Meet us at Booking.com HQ (Mon 18:30-21:00) & vCluster booth #521 (Tue 24 Mar, 12:30-1:30pm) β€” free book giveaway!RSVP Booking.com Event
Configuration beginner ⏱ 10 minutes K8s 1.21+

terminationGracePeriodSeconds Default

Configure Kubernetes terminationGracePeriodSeconds for graceful pod shutdown. Default 30s, SIGTERM handling, preStop hooks, and per-container settings.

By Luca Berton β€’ β€’ πŸ“– 5 min read

πŸ’‘ Quick Answer: terminationGracePeriodSeconds defaults to 30 seconds. When a pod is deleted, Kubernetes sends SIGTERM, waits this duration for graceful shutdown, then sends SIGKILL. Set higher for slow-draining apps (databases, message queues).

The Problem

Your application needs time to:

  • Finish processing in-flight requests
  • Close database connections cleanly
  • Flush buffers and commit pending writes
  • Deregister from service discovery
  • Complete background job processing

The default 30s may be too short for some workloads or too long for fast-terminating ones.

The Solution

Default Behavior (30 seconds)

apiVersion: v1
kind: Pod
metadata:
  name: myapp
spec:
  # Default: 30 seconds (omitting is the same as setting 30)
  terminationGracePeriodSeconds: 30
  containers:
    - name: app
      image: myapp:1.0.0

Custom Grace Period

apiVersion: apps/v1
kind: Deployment
metadata:
  name: kafka-consumer
spec:
  template:
    spec:
      # Long grace period for message processing
      terminationGracePeriodSeconds: 120
      containers:
        - name: consumer
          image: kafka-consumer:1.0.0
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-proxy
spec:
  template:
    spec:
      # Short grace period β€” nginx drains fast
      terminationGracePeriodSeconds: 5
      containers:
        - name: nginx
          image: nginx:1.27

Pod Termination Sequence

sequenceDiagram
    participant K as Kubelet
    participant C as Container
    participant P as preStop Hook
    
    K->>C: Remove from Service endpoints
    K->>P: Execute preStop hook (if defined)
    P-->>K: preStop completes
    K->>C: Send SIGTERM
    Note over K,C: terminationGracePeriodSeconds countdown starts
    C->>C: Graceful shutdown logic
    C-->>K: Process exits (code 0)
    Note over K: OR timeout expires
    K->>C: Send SIGKILL (forced kill)

With preStop Hook

spec:
  terminationGracePeriodSeconds: 60
  containers:
    - name: app
      image: myapp:1.0.0
      lifecycle:
        preStop:
          exec:
            command: ["/bin/sh", "-c", "sleep 5 && kill -SIGTERM 1"]
          # OR
          httpGet:
            path: /shutdown
            port: 8080

Important: preStop hook time is INCLUDED in terminationGracePeriodSeconds. If preStop takes 10s and grace period is 30s, your app only has 20s for SIGTERM handling.

WorkloadRecommendedReason
Stateless web server5-15sFast connection drain
API gateway15-30sWait for in-flight requests
Database60-120sWAL flush, connection close
Message queue consumer60-300sFinish processing batch
ML inference30-60sComplete current request
Batch job600-3600sJob may take hours
Init/sidecar5sFast cleanup

Application SIGTERM Handler

# Python example
import signal
import sys

def graceful_shutdown(signum, frame):
    print("SIGTERM received, shutting down...")
    # Close database connections
    db.close()
    # Flush metrics
    metrics.flush()
    # Stop accepting new requests
    server.stop(grace=10)
    sys.exit(0)

signal.signal(signal.SIGTERM, graceful_shutdown)
// Go example
ctx, stop := signal.NotifyContext(context.Background(), syscall.SIGTERM)
defer stop()

<-ctx.Done()
log.Println("Shutting down gracefully...")
server.Shutdown(context.Background())

Common Issues

IssueCauseFix
Pod killed before finishingGrace period too shortIncrease terminationGracePeriodSeconds
Pod hangs after deleteApp ignores SIGTERMHandle SIGTERM in code or use preStop
Rolling update too slowHigh grace period Γ— many podsReduce grace period or increase maxUnavailable
preStop + SIGTERM timeoutBoth share the same countdownSet grace period = preStop time + app drain time
Container gets SIGKILL immediatelyterminationGracePeriodSeconds: 0Don’t set to 0 in production

Best Practices

  1. Always handle SIGTERM in your application β€” don’t rely on SIGKILL
  2. Set grace period = actual drain time + 5s buffer β€” not excessively high
  3. Use preStop sleep 5 for load balancer deregistration race condition
  4. Test with kubectl delete pod --grace-period=0 only in development
  5. Monitor pod_termination_duration metrics β€” know how long your pods actually take

Key Takeaways

  • Default is 30 seconds β€” sufficient for most web apps
  • SIGTERM is sent AFTER preStop hook completes (same countdown timer)
  • After grace period expires, SIGKILL is sent unconditionally β€” no negotiation
  • Set based on actual workload needs: 5s for nginx, 300s for Kafka consumers
  • Rolling updates multiply this: 3 replicas Γ— 120s = potentially 6 minutes for full rollout
#termination #graceful-shutdown #sigterm #prestop #pod-lifecycle
Luca Berton
Written by Luca Berton

Principal Solutions Architect specializing in Kubernetes, AI/GPU infrastructure, and cloud-native platforms. Author of Kubernetes Recipes and creator of CopyPasteLearn courses.

Kubernetes Recipes book cover

Want More Kubernetes Recipes?

This recipe is from Kubernetes Recipes, our 750-page practical guide with hundreds of production-ready patterns.

Luca Berton Ansible Pilot Ansible by Example Open Empower K8s Recipes Terraform Pilot CopyPasteLearn ProteinLens