{"componentChunkName":"component---src-templates-tag-js","path":"/tags/http/","result":{"data":{"site":{"siteMetadata":{"title":"LoginRadius Blog"}},"allMarkdownRemark":{"totalCount":1,"edges":[{"node":{"fields":{"slug":"/engineering/tune-the-go-http-client-for-high-performance/"},"html":"<p>HTTP (hypertext transfer protocol) is a communication protocol that transfers data between client and server. HTTP requests are very essential to access resources from the same or remote server. In Golang, the <code>net/http</code> package comes with the default settings that we need to adjust according to our high-performance requirement.</p>\n<p>For setting up HTTP clients for making requests, most programming languages have different frameworks in place. We will take a hands-on approach in the coming sections to explore how HTTP requests can be made in Golang or Go, as I will refer to the language for the rest of the post.</p>\n<p>While working on the <a href=\"https://www.loginradius.com/blog/engineering/golang-maps/\">Golang projects</a>, I realized that improper configuration of HTTP might crash your server anytime.</p>\n<p>In the time when I was working with HTTP Client, I Observed some problems and their solutions, listed below:</p>\n<h2 id=\"problem1-default-http-client\" style=\"position:relative;\"><a href=\"#problem1-default-http-client\" aria-label=\"problem1 default http client permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Problem:1 Default Http Client</h2>\n<p>The HTTP client does not contain the request timeout setting by default.\nIf you are using http.Get(URL) or &#x26;Client{} that uses the http.DefaultClient. DefaultClient has not timeout setting; it comes with <code>no timeout</code></p>\n<p>Suppose the Rest API where you are making the request is broken, not sending the response back that keeps the connection open. More requests came, and open connection count will increase, Increasing server resources utilization, resulting in crashing your server when resource limits are reached.</p>\n<h3 id=\"solution-dont-use-the-default-http-client-always-specify-the-timeout-in-httpclient-according-to-your-use-case\" style=\"position:relative;\"><a href=\"#solution-dont-use-the-default-http-client-always-specify-the-timeout-in-httpclient-according-to-your-use-case\" aria-label=\"solution dont use the default http client always specify the timeout in httpclient according to your use case permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Solution: Don't use the default HTTP client, always specify the timeout in http.Client according to your use case</h3>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"\" data-index=\"0\"><code class=\"grvsc-code\"><span class=\"grvsc-line\">var httpClient = &http.Client{</span>\n<span class=\"grvsc-line\">  Timeout: time.Second * 10,</span>\n<span class=\"grvsc-line\">}</span></code></pre>\n<p>For the Rest API, it is recommended that timeout should not more than 10 seconds.\nIf the Requested resource is not responded to in 10 seconds, the HTTP connection will be canceled with net/http: request canceled (Client.Timeout exceeded ...) error.</p>\n<h2 id=\"problem2-default-http-transport\" style=\"position:relative;\"><a href=\"#problem2-default-http-transport\" aria-label=\"problem2 default http transport permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Problem:2 Default Http Transport</h2>\n<p>By default, the Golang Http client performs the connection pooling. When the request completes, that connection remains open until the idle connection timeout (default is 90 seconds). If another request came, that uses the same established connection instead of creating a new connection, after the idle connection time, the connection will return to the pool.</p>\n<p>Using the connection pooling will keep less connection open and more requests will be served with minimal server resources.</p>\n<p>When we not defined transport in the http.Client, it uses the default transport <a href=\"https://golang.org/src/net/http/transport.go\">Go HTTP Transport</a></p>\n<p>Default configuration of the HTTP Transport, </p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"\" data-index=\"1\"><code class=\"grvsc-code\"><span class=\"grvsc-line\">var DefaultTransport RoundTripper = &Transport{</span>\n<span class=\"grvsc-line\">\t...</span>\n<span class=\"grvsc-line\">\tMaxIdleConns:          100,</span>\n<span class=\"grvsc-line\">\tIdleConnTimeout:       90 * time.Second,</span>\n<span class=\"grvsc-line\">\t...</span>\n<span class=\"grvsc-line\">}</span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\">const DefaultMaxIdleConnsPerHost = 2</span></code></pre>\n<p>MaxIdleConns is the connection pool size, and this is the maximum connection that can be open; its default value is 100 connections.</p>\n<p>There is problem with the default setting <code>DefaultMaxIdleConnsPerHost</code> with value of 2 connection,\nDefaultMaxIdleConnsPerHost is the number of connection can be allowed to open per host basic.\nMeans for any particular host out of 100 connection from the connection pool only two connection will be allocated to that host.</p>\n<p>With the more request came, it will process only two requests; other requests will wait for the connection to communicate with the host server and go in the <code>TIME_WAIT</code> state. As more request came, increase the connection to the <code>TIME_WAIT</code> state and increase the server resource utilization; at the limit, the server will crash.</p>\n<h3 id=\"solution-dont-use-default-transport-and-increase-maxidleconnsperhost\" style=\"position:relative;\"><a href=\"#solution-dont-use-default-transport-and-increase-maxidleconnsperhost\" aria-label=\"solution dont use default transport and increase maxidleconnsperhost permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Solution: Don't use Default Transport and increase MaxIdleConnsPerHost</h3>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"\" data-index=\"2\"><code class=\"grvsc-code\"><span class=\"grvsc-line\">t := http.DefaultTransport.(*http.Transport).Clone()</span>\n<span class=\"grvsc-line\">t.MaxIdleConns = 100</span>\n<span class=\"grvsc-line\">t.MaxConnsPerHost = 100</span>\n<span class=\"grvsc-line\">t.MaxIdleConnsPerHost = 100</span>\n<span class=\"grvsc-line\">\t</span>\n<span class=\"grvsc-line\">httpClient = &http.Client{</span>\n<span class=\"grvsc-line\">  Timeout:   10 * time.Second,</span>\n<span class=\"grvsc-line\">  Transport: t,</span>\n<span class=\"grvsc-line\">}</span></code></pre>\n<p>By increasing connection per host and the total number of idle connection, this will increase the performance and serve more request with minimal server resources.</p>\n<p>Connection pool size and connection per host count can be increased as per server resources and requirements.</p>\n<h2 id=\"conclusion\" style=\"position:relative;\"><a href=\"#conclusion\" aria-label=\"conclusion permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Conclusion</h2>\n<p>In this article, we discussed the problems around the 'net/http' client default configurations. By changing some of the default settings of HTTP Client, we can achieve a High-performance HTTP client for production use. If you want to learn more about http, here is an interesting post on <a href=\"https://www.loginradius.com/blog/engineering/http-security-headers/\">HTTP security headers</a> If you like what you read, share your thoughts in the comment section.</p>\n<style class=\"grvsc-styles\">\n  .grvsc-container {\n    overflow: auto;\n    -webkit-overflow-scrolling: touch;\n    padding-top: 1rem;\n    padding-top: var(--grvsc-padding-top, var(--grvsc-padding-v, 1rem));\n    padding-bottom: 1rem;\n    padding-bottom: var(--grvsc-padding-bottom, var(--grvsc-padding-v, 1rem));\n    border-radius: 8px;\n    border-radius: var(--grvsc-border-radius, 8px);\n    font-feature-settings: normal;\n  }\n  \n  .grvsc-code {\n    display: inline-block;\n    min-width: 100%;\n  }\n  \n  .grvsc-line {\n    display: inline-block;\n    box-sizing: border-box;\n    width: 100%;\n    padding-left: 1.5rem;\n    padding-left: var(--grvsc-padding-left, var(--grvsc-padding-h, 1.5rem));\n    padding-right: 1.5rem;\n    padding-right: var(--grvsc-padding-right, var(--grvsc-padding-h, 1.5rem));\n  }\n  \n  .grvsc-line-highlighted {\n    background-color: var(--grvsc-line-highlighted-background-color, transparent);\n    box-shadow: inset var(--grvsc-line-highlighted-border-width, 4px) 0 0 0 var(--grvsc-line-highlighted-border-color, transparent);\n  }\n  \n  .dark-default-dark {\n    background-color: #1E1E1E;\n    color: #D4D4D4;\n  }\n</style>","frontmatter":{"date":"January 12, 2021","updated_date":null,"title":"How to Use the HTTP Client in GO To Enhance Performance","tags":["Golang","HTTP","Performance"],"coverImage":{"childImageSharp":{"fluid":{"aspectRatio":1.7699115044247788,"src":"/static/68276d4b4277ad09e329598038e91917/14b42/index.jpg","srcSet":"/static/68276d4b4277ad09e329598038e91917/f836f/index.jpg 200w,\n/static/68276d4b4277ad09e329598038e91917/2244e/index.jpg 400w,\n/static/68276d4b4277ad09e329598038e91917/14b42/index.jpg 800w,\n/static/68276d4b4277ad09e329598038e91917/47498/index.jpg 1200w,\n/static/68276d4b4277ad09e329598038e91917/ec6c5/index.jpg 1280w","sizes":"(max-width: 800px) 100vw, 800px"}}},"author":{"id":"Mayank Agarwal","github":"mayankagrwal","avatar":null}}}}]}},"pageContext":{"tag":"HTTP"}},"staticQueryHashes":["1171199041","1384082988","2100481360","23180105","528864852"]}