Skip to content

Batch HTTP/2 upload body flushes#2264

Open
pavel-ptashyts wants to merge 3 commits into
AsyncHttpClient:mainfrom
maygemdev:perf/http2-upload-flush-batching
Open

Batch HTTP/2 upload body flushes#2264
pavel-ptashyts wants to merge 3 commits into
AsyncHttpClient:mainfrom
maygemdev:perf/http2-upload-flush-batching

Conversation

@pavel-ptashyts

@pavel-ptashyts pavel-ptashyts commented Jul 19, 2026

Copy link
Copy Markdown
Contributor

Summary

  • batch HTTP/2 upload DATA frame flushes while the stream remains writable
  • flush only when the body pump yields for source suspension/backpressure or writes the terminal DATA frame
  • prevent synchronous writability callbacks from re-entering the pump
  • keep the pump parked while the terminal DATA write is pending, preventing duplicate endStream frames
  • cover multi-chunk batching, suspension, backpressure resume, re-entry, and cleanup timing in Http2BodyWriterTest

Rationale

The HTTP/2 upload body pump previously flushed after every intermediate DATA chunk. That kept writes moving, but it also forced one flush per chunk even when the stream child channel stayed writable. Batching until a yield point preserves bounded in-flight data while reducing flush overhead for multi-chunk uploads.

Netty may synchronously fire channelWritabilityChanged from flush(). Explicit pumping and terminal-write states prevent that callback from mutating pump state recursively or emitting a second terminal frame before the first write completes.

Validation

  • ./mvnw -pl client -Dtest='org.asynchttpclient.netty.request.body.Http2BodyWriterTest' test (3 tests)
  • ./mvnw -pl client -DskipTests compile
  • ./mvnw -pl client -Dtest=Http2StreamingBodyFlowControlTest test
  • ./mvnw -pl client -Dtest=BasicHttp2Test test

Attribution

Codex on behalf of Pavel Ptashyts

@pavel-ptashyts
pavel-ptashyts force-pushed the perf/http2-upload-flush-batching branch from fa6ab1b to 87d1017 Compare July 20, 2026 08:50
pavel-ptashyts and others added 3 commits July 20, 2026 17:04
Avoid flushing every intermediate HTTP/2 DATA chunk produced by
Http2BodyWriter. The pump now flushes when it yields for source
suspension, when backpressure makes the stream unwritable, or when
it writes the terminal DATA frame.

This preserves bounded in-flight write behavior while reducing
per-chunk flush overhead for multi-chunk uploads. Add a focused unit
test for the single terminal flush path while the stream remains
writable.

Codex on behalf of Pavel Ptashyts

Co-Authored-By: Codex <codex@openai.com>
Flush batching is correct only if every point that parks the body
pump flushes already-written DATA frames and can resume without losing
the pending chunk.

Cover source suspension and persistent channel backpressure in addition
to the writable happy path. Correct the new test file's license year
to match the repository contribution rules.

Codex on behalf of Pavel Ptashyts

Co-Authored-By: Codex <codex@openai.com>
Prevent synchronous writability callbacks from re-entering the
HTTP/2 body pump and keep the pump parked until its terminal DATA
write completes.

Extend the writer test to trigger a nested callback during terminal
flush and verify that one endStream frame is written and source
cleanup waits for write completion.

Codex on behalf of Pavel Ptashyts

Co-Authored-By: Codex <codex@openai.com>
@pavel-ptashyts
pavel-ptashyts force-pushed the perf/http2-upload-flush-batching branch from 5e9d2a3 to 531b85e Compare July 20, 2026 15:08
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant