Go HTTP timeouts #
Using the HTTP server or client, it’s very common to get the timeouts wrong. This is especially true when using the global instances, since they do provide any default timeouts.
If the Go HTTP server is used to serve a public webpage, you’ll soon find yourself out of file descriptors.
Server timeouts #
There are two properties on a HTTP server controlling the timeouts, namely
ReadTimeout
and WriteTimeout
.
import "net/http"
srv := &http.Server{
ReadTimeout: 45*time.Second,
WriteTimeout: 45*time.Second,
ReadHeaderTimeout: 5*time.Second,
}
ReadTimeout
is used to control the read timeout, and includes
the time elapsed from the moment a TCP connection is accepted to the moment when
the request body is read.
WriteTimeout
is used to control the write timeout, and includes
the time elapsed from the moment the last HTTP header is read to the moment when
the response body is written.
ReadHeaderTimeout
is used to control the timeout for reading the headers, and
includes the time elapsed from the moment the first header is read to the moment
when the last header is read.
The below diagram shows the timeouts.
+--------+---------------+-------------------+----------+----------+
| Accept | TLS handshake | Req. header | Req. body| Response |
+--------+---------------+-------------------+----------+----------+
+------------ReadTimeout--------------------->
+-ReadHeaderTimeout->
+--WriteTimeout------->