Go

Why is http.ListenAndServe(":8080", nil) not production-ready? Explain each server timeout.

Question 446HardGo 1.22 to 1.25

The package-level helper creates an http.Server with zero timeouts, meaning a client can hold a connection forever (Slowloris: dribble headers one byte at a time and exhaust file descriptors/goroutines). It also uses DefaultServeMux, which any imported package (e.g. net/http/pprof) can register on.

  • ReadHeaderTimeout — time to read request headers. The key Slowloris defense; gosec (G112) flags its absence (go vet does not).
  • ReadTimeout — whole request including body. Too small breaks large uploads; can be extended per request with ResponseController.SetReadDeadline.
  • WriteTimeout — from end of header read to end of response write. Kills long-polling/SSE unless extended per request with http.ResponseController.SetWriteDeadline.
  • IdleTimeout — how long a keep-alive connection waits for the next request (defaults to ReadTimeout if zero).
  • MaxHeaderBytes — defaults to 1 MB.
srv := &http.Server{
	Addr:              ":8080",
	Handler:           mux,
	ReadHeaderTimeout: 5 * time.Second,
	ReadTimeout:       30 * time.Second,
	WriteTimeout:      30 * time.Second,
	IdleTimeout:       120 * time.Second,
}
log.Fatal(srv.ListenAndServe())

Server timeouts are connection-level; for per-handler business deadlines use http.TimeoutHandler or context.WithTimeout(r.Context(), ...). Timeouts close the connection but do not stop your handler goroutine — the handler must honor context cancellation.

More on Standard Library, HTTP & Systems Design in Go

All 35 Standard Library, HTTP & Systems Design in Go questions