You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Related: memory pinned by HTTP/2 receive windows on slow streams. The windows are fixed (1 MiB per stream on the server, 4 MiB on the Transport), so every long-lived body whose reader lags behind the link holds a full window of unread data.
Have you considered receive-window autotuning, as in kernel TCP, gRPC-Go's BDP estimator or quic-go? For example: start at 64 KiB, grow to 2× what the body reader consumed per RTT (RTT from PING), shrink gradually when the reader slows down, and never exceed the current fixed values.
A prototype of this, done as a frame-level shim under net/http in a proxy. The code and the measurements below were produced by an AI assistant (Claude) on a local test bench (100 Mbit/s, 50 ms RTT, 30 sessions):
Inside net/http this would be both simpler and architecturally cleaner: the body reader knows exactly when data is consumed, while a shim has to infer it from WINDOW_UPDATE frames.
Activity
gopherbot commentedon Aug 5, 2026
Change https://go.dev/cl/810780 mentions this issue:
net/http/internal/http2: let Transport's request-write goroutine exit earlygabyhelp commentedon Aug 5, 2026
Related Issues
(Emoji vote if this was helpful or unhelpful; more detailed feedback welcome in this discussion.)
net/http/internal/http2: let Transport's request-write goroutine exit…
gopherbot commentedon Aug 6, 2026
Change https://go.dev/cl/811680 mentions this issue:
net/http/internal/http2: release handler write buffers when idlenet/http/internal/http2: release handler write buffers when idle
cagedmantis commentedon Aug 17, 2026
@neild @ianlancetaylor @nicholashusin
gopherbot commentedon Sep 5, 2026
Change https://go.dev/cl/828206 mentions this issue:
net/http/internal/http2: don't pin frame-sized write buffers on idle connsgopherbot commentedon Sep 5, 2026
Change https://go.dev/cl/828205 mentions this issue:
net/http/internal/http2: don't pin frame-sized read buffers on idle connsgopherbot commentedon Sep 5, 2026
Change https://go.dev/cl/828204 mentions this issue:
net/http/internal/http2: turn Framer.getReadBuf func field into a method[-]net/http/internal/http2: reduce memory usage[/-][+]net/http{,/internal/http2}: reduce memory usage[/+]gopherbot commentedon Sep 6, 2026
Change https://go.dev/cl/828504 mentions this issue:
net/http: don't pin bufio buffers on idle HTTP/1 keep-alive connectionsnet/http/internal/http2: turn Framer.getReadBuf func field into a method
net/http: don't pin bufio buffers on idle HTTP/1 keep-alive connections
7 remaining items
gopherbot commentedon Sep 9, 2026
Change https://go.dev/cl/830364 mentions this issue:
net/http: don't require timeout errors to wrap os.ErrDeadlineExceededgopherbot commentedon Sep 9, 2026
Change https://go.dev/cl/830365 mentions this issue:
net/http: don't require timeout errors to wrap os.ErrDeadlineExceededgopherbot commentedon Sep 9, 2026
Change https://go.dev/cl/830384 mentions this issue:
net/http: release HTTP/1 empty buffers immediately for keep-alive connectionsnet/http: fix two bugs from CL 828504
gopherbot commentedon Sep 11, 2026
Change https://go.dev/cl/831084 mentions this issue:
net/http/internal/http2: let the server's serve goroutine exit when idlenet/http/internal/http2: let the server's serve goroutine exit when idle
gopherbot commentedon Sep 14, 2026
Change https://go.dev/cl/832504 mentions this issue:
net/http/internal/http2: do some follow-ups to serve parking changenet/http/internal/http2: do some follow-ups to serve parking change
gopherbot commentedon Sep 15, 2026
Change https://go.dev/cl/833344 mentions this issue:
net/http: don't pin bufio buffers on conns handed off to HTTP/2net/http: don't pin bufio buffers on conns handed off to HTTP/2
gopherbot commentedon Sep 17, 2026
Change https://go.dev/cl/834084 mentions this issue:
net/http/internal/http2: replace parkMu with a single atomic wordnet/http/internal/http2: replace parkMu with a single atomic word
[tailscale-cherrypick] net/http/internal/http2: replace parkMu with a…
Medium1992 commentedon Sep 30, 2026
Related: memory pinned by HTTP/2 receive windows on slow streams. The windows are fixed (1 MiB per stream on the server, 4 MiB on the Transport), so every long-lived body whose reader lags behind the link holds a full window of unread data.
Have you considered receive-window autotuning, as in kernel TCP, gRPC-Go's BDP estimator or quic-go? For example: start at 64 KiB, grow to 2× what the body reader consumed per RTT (RTT from PING), shrink gradually when the reader slows down, and never exceed the current fixed values.
A prototype of this, done as a frame-level shim under net/http in a proxy. The code and the measurements below were produced by an AI assistant (Claude) on a local test bench (100 Mbit/s, 50 ms RTT, 30 sessions):
Steady-state throughput is unchanged. The cost is a slower ramp for new streams: 5-second transfers were 3% slower at 30 ms RTT, 13% at 80 ms and 30% at 150 ms. Code: https://github.com/Medium1992/Xray-core-fork/blob/feat/xhttp-mux-cool/transport/internet/splithttp/h2flow.go
Inside net/http this would be both simpler and architecturally cleaner: the body reader knows exactly when data is consumed, while a shim has to infer it from WINDOW_UPDATE frames.