Graceful shutdown — это когда приложение не просто убивается, а сначала дожидается завершения текущих запросов.
Ловишь SIGTERM через signal.Notify, вызываешь srv.Shutdown(ctx) с таймаутом — он перестаёт принимать новые соединения, но даёт текущим запросам доработать. После этого закрываешь БД, кэш и прочее.
quit := make(chan os.Signal, 1)
signal.Notify(quit, syscall.SIGINT, syscall.SIGTERM)
<-quit
ctx, cancel := context.WithTimeout(
context.Background(),
30*time.Second,
)
defer cancel()
srv.Shutdown(ctx)
db.Close()
Если в таймаут не уложился — всё равно гасишь. Лучше потерять пару запросов чем зависнуть навечно.