Search code examples
gohttpconnection-poolinggo-http

Interactions between Golang http.Client.Timeout and http.Transport.MaxConnsPerHost


The docs for http.Client.Timeout says: The timeout includes connection time, any redirects, and reading the response body

The docs for http.Transport.MaxConnsPerHost says: MaxConnsPerHost optionally limits the total number of connections per host, including connections in the dialing, active, and idle states. On limit violation, dials will block.

I have a few questions:

  1. Does timeout connection time include time stuck in the queue waiting on available connection if current number of connections equals http.Transport.MaxConnsPerHost?

  2. What does a dial encompass?

  3. If yes to question 1, is it possible to set a timeout for client request that does not including waiting for available connection due to MaxConnsPerHost limit?

I currently have both set and I'm getting client timeouts where I have lots of simultaneous connections even though my timeout is plenty enough for any single http request and server side doesn't seem to be a bottleneck


Solution

  • Does timeout connection time include time stuck in the queue waiting on available connection if current number of connections equals http.Transport.MaxConnsPerHost?

    MaxConnsPerHost applies per RoundTrip call, so yes, http.Client.Timeout includes the time spent waiting in the queue, which can even be multiple times - for the initial request and for each redirect.

    What does a dial encompass?

    In Go terminology, "dialing" means establishing a connection. In case of HTTP it involves making a TCP connect call to the server.

    If yes to question 1, is it possible to set a timeout for client request that does not including waiting for available connection due to MaxConnsPerHost limit?

    Since an HTTP request potentially involves making multiple round-trips to the server, the simple answer to this question is no.

    You can set other timeouts though:

    Or write your own RoundTripper wrapper that implements MaxConnsPerHost functionality and sets the context timeout before passing it down to the default transport.

    It all depends on what you're trying to achieve.