Hi @phil, sorry for the really slow reply, but this took a bit more to play around to see what is happening.
After some amount of debugging, this seems to come from http2 WINDOW_UPDATE
send each time go (the language k6 is written in) reads from the connection.
Relevant stack trace:
runtime/debug.PrintStack()
runtime/debug/stack.go:16 +0x19
go.k6.io/k6/lib/netext.(*Conn).Write(0xc000574000, {0xc0005310e0, 0xc0005310e5, 0x4746ce})
go.k6.io/k6/lib/netext/dialer.go:270 +0xa5
crypto/tls.(*Conn).write(0xc001ccc000, {0xc0005310e0, 0x5, 0x5d})
crypto/tls/conn.go:912 +0x108
crypto/tls.(*Conn).writeRecordLocked(0xc001ccc000, 0x17, {0xc0004bb000, 0xd, 0x1000})
crypto/tls/conn.go:980 +0x351
crypto/tls.(*Conn).Write(0xc0026060c8, {0xc0004bb000, 0xd, 0x1000})
crypto/tls/conn.go:1151 +0x405
golang.org/x/net/http2.stickyErrWriter.Write({{0x7f8318315780, 0xc001ccc000}, 0xc0023402b8}, {0xc0004bb000, 0xc002606120, 0xba177a})
golang.org/x/net@v0.0.0-20211209100829-84cba5454caf/http2/transport.go:398 +0x4f
bufio.(*Writer).Flush(0xc001a52240)
bufio/bufio.go:607 +0x62
golang.org/x/net/http2.transportResponseBody.Read({0xc00135cc00}, {0xc000a49e00, 0x7f8318315af0, 0xc002606210})
golang.org/x/net@v0.0.0-20211209100829-84cba5454caf/http2/transport.go:2308 +0x46c
bytes.(*Buffer).ReadFrom(0xc00135cc00, {0x7f8318315ab0, 0xc002340300})
bytes/buffer.go:204 +0x98
io.copyBuffer({0x12f4d20, 0xc00135cc00}, {0x7f8318315ab0, 0xc002340300}, {0x0, 0x0, 0x0})
io/io.go:409 +0x14b
io.Copy(...)
io/io.go:382
go.k6.io/k6/lib/netext/httpext.readResponseBody(0xc00235c000, 0x0, 0xc0024be090, {0x0, 0x0})
go.k6.io/k6/lib/netext/httpext/compression.go:197 +0x6b3
go.k6.io/k6/lib/netext/httpext.MakeRequest({0x13105a8, 0xc0024d65a0}, 0xc00235c000, 0xc0024be480)
go.k6.io/k6/lib/netext/httpext/request.go:299 +0x1625
This results in 42 bytes written back (before additional bytes for other layers such as TCP and IP)
On k6/lib/netext/httpext/compression.go:197
k6 is reading the response
On The Go Programming Language (link to code) we can see that we flush back after calling WriteWindowUpdate
This seems like way too aggressive on go’s side. Browsers (and curl) seem to just seem to not update the window at all(after the beginning) at least with the small requests I had.
It seems like that has been reported x/net/http2: WINDOW_UPDATE sent rate too high and can't be configured · Issue #28732 · golang/go · GitHub but nothing has been done.
As confirmation on the fact this are the same packages - if we log from k6 to a ssl keylog file and user that in wireshark that same packages become http2 WINDOW_UPDATE
and the payload is exactly 42 bytes
This probably isn’t really a problem in most cases and there really is nothing we can do apart from maybe trying to fix it upstream, which seems just a bit daunting. Looking at the code it won’t be super easy to just skip that given some condition. If anything parts of it look like they are trying to prevent exactly this but … don’t. But also all of this code is 6+ years old, so
Some stackoverflow question with some info around “how often should window_update be issued?”