go 25 lines · 1 tab

Graceful gRPC shutdown with fallback to Stop

Leah Thompson Jan 2026
1 tab
package main

import (
  "time"

  "google.golang.org/grpc"
)

func ShutdownGRPC(s *grpc.Server, timeout time.Duration) {
  done := make(chan struct{})
  go func() {
    s.GracefulStop()
    close(done)
  }()

  t := time.NewTimer(timeout)
  defer t.Stop()
  select {
  case <-done:
    return
  case <-t.C:
    s.Stop()
    return
  }
}
1 file · go Explain with highlit

For gRPC services, GracefulStop is ideal because it allows in-flight RPCs to finish, but it can hang if handlers ignore cancellation or if clients never close streams. I wrap shutdown in a deadline: call GracefulStop in a goroutine, and if it doesn’t return in time, call Stop to force-close connections. The important operational habit is consistency: on deploy, you want the instance to drain quickly and predictably. I also use a root context canceled by signals so handlers can return promptly. This pattern prevents the “pods stuck terminating” problem and avoids dropping requests mid-flight unnecessarily. In production I log shutdown start/end and export a gauge for in-flight requests so you can see whether the service drains cleanly.


Related snips

Share this code

Here's the card — post it anywhere.

Graceful gRPC shutdown with fallback to Stop — share card
Link copied