How To Do Graceful Shutdown for Go HTTP Server

Hi, I am a cat lover and software engineer from Malang, mostly doing PHP and stuff. Software Engineer Live in Malang, Indonesia Visit my resume and portfolios at didiktrisusanto.dev See you, folks!
Long time no see. After took a long break, I finally started to writing again. I missed code with Go so I decided to share about Graceful shutdown in this post.
Graceful shutdown is safer and proper way to shutdown your HTTP server especially in Go where we usually managed the server script by ourself.
The “Graceful shutdown function” facilitates this process, allowing the server to transition smoothly without abruptly terminating active connections.
The most basic and simple way to run the HTTP server in Go is like this
s := &http.Server{
Addr: ":8080",
Handler: mux,
ReadTimeout: 10 * time.Second,
WriteTimeout: 10 * time.Second,
}
log.Fatal(s.ListenAndServe())
s.ListenAndServe() is called to run the server and listen incoming http requests. Yes this works, but when we’re talking about production system, we need more proper way using graceful shutdown to prevent unexpected behavior when the server needs to be stopped.
Here’s how graceful shutdown would be
s := &http.Server{
Addr: ":8080",
Handler: mux,
}
stop := make(chan os.Signal, 1)
signal.Notify(stop, os.Interrupt, syscall.SIGTERM)
go func() {
if err := s.ListenAndServe(); !errors.Is(err, http.ErrServerClosed) {
log.Fatal(err)
}
log.Println("Stopped serving new connections")
}()
<-stop
log.Println("Shutting down gracefully...")
shutdownCtx, shutdownRelease := context.WithTimeout(context.Background(), 10*time.Second)
defer shutdownRelease()
if err := s.Shutdown(shutdownCtx); err != nil {
log.Printf("server shutdown error: %v\n", err)
}
log.Println("Server stoppped")
It’s using goroutine and channel to notify server if there is termination signal. More example of this implementation at my fun project simple real-time system monitoring using Go & HTMX.
Happy coding!



