Timeouts

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------->