Graceful shutdown in Go Fiber without dropping in-flight requests
Stop a Fiber server without dropping active requests. Use signal handling and app.Shutdown with a context timeout to drain in‑flight work, then exit cleanly.
08 Sept 2026, 01:38 UTC

Abruptly stopping a Fiber server drops active HTTP connections. Clients see connection resets and transactions that were in progress get cut off. The useful takeaway is to stop accepting new work while letting current requests finish, then exit.
Why in‑flight matters
In‑flight means a request that has been accepted but not yet written to the client. If the process exits during that window, the TCP connection is closed by the kernel and the client receives an error. A graceful stop keeps the listener closed so no new requests start, but the runtime is allowed to drain the existing work.
A context timeout is a deadline carried through Go code. When the deadline expires, Shutdown is allowed to force the stop. That deadline is your safety valve between waiting too long and cutting work off.
Minimal Fiber app with a slow handler
Start with a router, a logger middleware, and a handler that simulates work. The sleep makes the drain visible during testing.
package main
import (
"context"
"log"
"os/signal"
"syscall"
"time"
"github.com/gofiber/fiber/v2"
"github.com/gofiber/fiber/v2/middleware/logger"
)
func main() {
app := fiber.New()
app.Use(logger.New())
app.Get("/work", func(c *fiber.Ctx) error {
// Simulate work that respects the request context
select {
case <-time.After(5 * time.Second):
return c.SendString("done")
case <-c.Context().Done():
return nil
}
})
// Start server in background so we can handle signals
go func() {
if err := app.Listen(":3000"); err != nil {
log.Printf("listen error: %v", err)
}
}()
// Signal handling and graceful shutdown
quit := make(chan os.Signal, 1)
signal.Notify(quit, syscall.SIGINT, syscall.SIGTERM)
sig := <-quit
log.Printf("signal received: %v, starting graceful shutdown", sig)
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
defer cancel()
// Fiber v2.50+ Shutdown accepts a context for timeout control.
// Version assumption: check your Fiber version docs.
if err := app.Shutdown(ctx); err != nil {
log.Printf("shutdown error: %v", err)
}
log.Printf("shutdown finished")
}
Signal handling and shutdown flow
Attach an OS signal handler for SIGINT and SIGTERM. Those are the signals sent by Ctrl‑C and by orchestrators during rolling deploys. On signal, create a context with a timeout and call app.Shutdown.
Shutdown closes the listener so new connections are refused, then waits for active handlers. Handlers should respect c.Context().Done() to avoid work after cancellation. Middleware that does blocking I/O after Shutdown is called may not finish before the process exits.
Risk: a handler that ignores the request context will continue running even after Shutdown starts, potentially leaking resources or holding the process past the timeout.
Trade‑off: latency vs safety
The timeout adds latency to service termination. A 10 second timeout means the process can stay alive up to 10 seconds after SIGTERM. If any handler exceeds the timeout, Fiber forces the close and the client may receive a partial response or error.
Set the timeout based on your longest expected request duration plus a margin. Shorter timeouts speed up deploys but increase the chance of forced closes. Longer timeouts improve safety but delay rolling updates.
Actionable check
Start the binary, send a request to /work, then send SIGTERM to the process from another terminal with kill -TERM <pid>. The server should stop accepting new connections while the in‑flight request is allowed to finish within the timeout, then exit.
Verify behavior by observing logs for the signal receipt and shutdown finish messages, and by confirming that a new request after the signal is refused while the first request completes. Automate this with a small script that launches the binary, issues curl, sends SIGTERM via os/exec, and asserts a zero exit code and no error logs.
Limitations: custom middleware and handlers must propagate context cancellation. Avoid synchronous disk writes or external calls after calling Shutdown, as the process may be forced to exit before they complete.
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.