TL;DR
Get business pricing on monitors, keyboards and dev gear
- Business-only prices and quantity discounts
- Tax-exempt purchasing
- Multiple users, one account, clear invoices
A Go blog report says a repeated HTTP/1 request test took about 150 milliseconds on Go 1.27, compared with about 710 milliseconds on Go 1.26. The change addresses a connection-reuse problem when an application closes a response without reading its body; the report does not provide broader benchmark results or the full implementation details in the supplied material.
A Go 1.27 HTTP/1 change improves connection reuse when client code closes a response body without reading it, according to a report on the Go project website. In the report’s example, 100 requests to index.golang.org took about 150 milliseconds on Go 1.27, compared with about 710 milliseconds on Go 1.26, when HTTP/2 was disabled.
The example function sends an HTTP GET request, checks for an error, defers resp.Body.Close(), and returns the status code without consuming the response body. The report says this pattern repeatedly created new connections through Go 1.26 when used with HTTP/1. That meant requests could pay the costs of establishing a TCP connection and, for HTTPS, negotiating TLS instead of reusing an existing connection.
With HTTP/1, response data travels sequentially over a connection. The client must read the current response body to its end before it can identify the beginning of the next response on that same stream. Previously, closing a body that still had unread data led the Go HTTP client to abandon the connection. The Go 1.27 report describes an improvement to this behavior and gives the faster result as an example of its effect.
The comparison used 100 calls to the same public endpoint with HTTP/2 disabled, using GODEBUG=http2client=0. The author reports measurements of roughly 710 ms on Go 1.26 and 150 ms on Go 1.27 on their machine. Those figures describe that particular test, not a general performance guarantee for all Go programs or HTTP services.
Fewer Repeated HTTP Handshakes
For applications that make many short HTTP/1 requests, avoiding unnecessary connection setup can reduce latency and TLS-handshake work. This is most relevant when a program needs only a status code or otherwise closes a response before consuming its body. The report’s example shows how a small, ordinary client pattern can have a large effect on repeated-request timing under the tested conditions.
The change may also reduce pressure on services and clients from repeatedly opening connections, although the supplied report provides no measurements of resource use or server-side effects. Applications using HTTP/2 are less exposed to this specific limitation: HTTP/2 multiplexes separate streams over a connection, so an unread body on one stream does not block other requests from using that connection in the same way.
The result does not mean developers should assume every response body can be ignored without consequences. Applications still need to handle response data appropriately, and performance will depend on factors such as response size, network latency, protocol, and server behavior. The key change described is the HTTP/1 client’s ability to reuse connections in the relevant unread-body case.
As an affiliate, we earn on qualifying purchases.
Why Unread Bodies Block HTTP/1
HTTP/1.1 connections are persistent by default unless one side indicates that the connection should close. Reuse can avoid repeating TCP and TLS setup for each request. But HTTP/1 responses on a connection are ordered as a continuous byte stream: the client cannot safely start parsing another response until it has reached the end of the current response body, as indicated by the response framing.
That constraint can affect code even when it does read most of a response. The Go report gives JSON decoding as an example: a decoder may stop after the closing brace of an object while leaving a trailing newline unread. If the remaining byte is not consumed, the body is not fully read and the connection may not have been reusable under the earlier behavior. Developers have commonly worked around this by draining a body before closing it, though doing so can mean reading data the application does not need.
The report contrasts HTTP/1 with HTTP/2, where multiple request and response streams can share one TCP connection. It also notes that connection establishment has a cost: TCP and TLS exchanges add round trips before an HTTPS request can be served. The example endpoint supports TLS 1.3, according to the report, yet the author still observed a substantial difference between the two Go versions in the specified test.
““On Go 1.27, the same program takes ~150 milliseconds.””
— Go project report
Go programming HTTP debugging tools
As an affiliate, we earn on qualifying purchases.
As an affiliate, we earn on qualifying purchases.
Benchmark Scope and Implementation
The supplied source reports one machine’s timing for one endpoint and does not give hardware specifications, repeated-run ranges, or results across different networks, response sizes, and servers. The 710 ms and 150 ms measurements therefore should not be treated as a universal speedup estimate. The source also does not provide enough detail here to describe the exact implementation mechanism or any limits on which unread response bodies can be followed by reuse.
It is also not clear from the supplied material whether the reported behavior applies identically to all HTTP/1 response types or how it interacts with particular server headers and connection-close conditions. The comparison specifically disables the HTTP/2 client, so it should not be used to infer a change in HTTP/2 performance.
HTTP connection reuse testing tools
As an affiliate, we earn on qualifying purchases.
As an affiliate, we earn on qualifying purchases.
What Go Users Should Check
Go users evaluating the change can compare their own workloads on Go 1.26 and Go 1.27, keeping the protocol, response handling, server, and network conditions consistent. The most relevant cases are repeated HTTP/1 requests where application code closes response bodies before reaching the end. Measurements should distinguish HTTP/1 from HTTP/2 and account for the response body and connection settings.
Developers should consult the Go 1.27 release information and the full Go project report for implementation details and guidance on response-body handling. The supplied report establishes the example result and explains the prior connection-reuse problem; broader performance impact and precise behavior across other workloads remain to be established.
As an affiliate, we earn on qualifying purchases.
Key Questions
What changed in Go 1.27?
The Go project report describes improved HTTP/1 connection reuse when client code closes a response body without reading it fully, addressing a case that previously caused the connection to be abandoned.
How large was the reported performance difference?
In the report’s test of 100 requests to index.golang.org with HTTP/2 disabled, the program took about 710 milliseconds on Go 1.26 and about 150 milliseconds on Go 1.27. The report says these are measurements from the author’s machine.
Does this result apply to every Go HTTP client?
No general result is established by the supplied benchmark. Timing depends on the application, protocol, server, response, and network. The reported comparison covers one specific HTTP/1 test.
Why did unread response bodies affect HTTP/1 reuse?
HTTP/1 responses share an ordered byte stream. The client needs to reach the end of one response body before it can locate the next response on that connection. Closing a body with unread data previously led the Go client to discard the connection in the described case.
Does the report describe a similar HTTP/2 issue?
The report says HTTP/2 does not have this particular blocking problem because it multiplexes streams over a connection. It does not report a Go 1.27 HTTP/2 performance change in the supplied material.
Source: hn
Halloween Picks
halloween
As an affiliate, we earn on qualifying purchases.
