What changed
In an October 14, 2026 technical explanation, the Go team detailed an HTTP/1 client change already shipped with Go 1.27 on August 19. When an HTTP response body is closed before it has been fully consumed, net/http.Transport now tries to drain remaining bytes asynchronously for at most 50 milliseconds or 256 KiB. When the drain completes, the underlying TCP/TLS connection can be reused. Previously Go 1.26 and earlier usually abandoned that connection. The change requires no new API and does not alter HTTP/2 stream reuse.
Why it matters
Status-only API checks and JSON decoders that leave a trailing newline unread can silently force fresh HTTP/1 connections, adding network round trips, TLS work and latency. This implementation-level change makes common idiomatic Go code faster without requiring callers to invent fragile manual draining routines. It particularly helps sequential small-body API traffic, while very large or slow responses still favour closing rather than waiting to download unwanted data.
The subtle performance trap in Close
In HTTP/1, the next response on a connection cannot be parsed until the current response body's end is known. Calling resp.Body.Close() without reading to EOF used to make Go discard the connection. This affects callers interested only in HTTP status and programs that decode a JSON object but leave a newline or other trailing bytes unread. HTTP/2 multiplexing already handles separate streams differently, so the same manual draining advice does not apply there.
Go 1.27 drains within a strict budget
When an HTTP/1 response body is closed early, net/http.Transport can continue draining it asynchronously, stopping after 256 KiB or 50 ms. If it reaches EOF, the connection is reusable. If not, it can be discarded without forcing the caller to wait for an arbitrarily slow or large response. It skips work where reuse is impossible, such as a Connection: close response. The upstream implementation issue documents the semantics-preserving change.
A fivefold benchmark is illustrative, not a universal speed claim
The Go team reports that 100 sequential HTTP/1 status requests to index.golang.org took about 710 ms on Go 1.26 and 150 ms on Go 1.27 on the author's machine. The improvement comes from avoiding repeated connection establishment in that specific setup. It is not a general claim that every Go HTTP client or HTTP/2 application is five times faster. Response size, RTT, protocol negotiation, server keep-alive behaviour and request concurrency all matter.
Why manual draining was risky
A common workaround was to io.Copy to io.Discard before Close. Unbounded draining can waste bandwidth or hang on a slow server; developers needed byte limits, timeouts and concurrency management. Go's transport now centralises that bounded behaviour. Developers should generally close bodies promptly and avoid redundant custom drain helpers added solely to force HTTP/1 reuse.
Practical migration and checks
Teams moving from Go 1.26 to 1.27 should benchmark representative HTTP/1 traffic and inspect connection reuse with tracing rather than assuming the headline gain. Review existing io.Copy(io.Discard, body) helpers: some may now be unnecessary, while others may intentionally consume data for application reasons. Keep closing response bodies and do not confuse this change with security advisories or HTTP/2 optimisations.