Go

Graceful HTTP Shutdown

admin by @admin ADMIN
Jun 15, 2026
May 31, 2026
Public
0 0 up · 0 down Sign in to vote
On SIGINT/SIGTERM, stop accepting new connections but let in-flight requests finish. The `http.Server.Shutdown` method does exactly that — with a deadline.
Go
Raw
package main

import (
    "context"
    "errors"
    "log"
    "net/http"
    "os/signal"
    "syscall"
    "time"
)

func main() {
    mux := http.NewServeMux()
    mux.HandleFunc("/", func(w http.ResponseWriter, _ *http.Request) {
        time.Sleep(2 * time.Second)              // pretend slow handler
        w.Write([]byte("ok"))
    })

    srv := &http.Server{Addr: ":8080", Handler: mux}

    // Listen for shutdown signals
    ctx, stop := signal.NotifyContext(context.Background(), syscall.SIGINT, syscall.SIGTERM)
    defer stop()

    go func() {
        if err := srv.ListenAndServe(); err != nil && !errors.Is(err, http.ErrServerClosed) {
            log.Fatal(err)
        }
    }()
    log.Println("listening on :8080")

    <-ctx.Done()                                  // block until a signal arrives
    log.Println("shutting down…")

    // Give in-flight requests up to 10 seconds to finish
    shutCtx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
    defer cancel()
    if err := srv.Shutdown(shutCtx); err != nil {
        log.Fatalf("forced shutdown: %v", err)
    }
    log.Println("server stopped")
}
Tags

Save your own code snippets

Create a free account and build your private vault. Share publicly whenever you want.