Skip to content

fix: configure HTTP/2 maxStreams=1 to prevent bidi stream starvation#10

Merged
VWang1111 merged 1 commit into
mainfrom
fix/http2-maxstreams-config
Apr 13, 2026
Merged

fix: configure HTTP/2 maxStreams=1 to prevent bidi stream starvation#10
VWang1111 merged 1 commit into
mainfrom
fix/http2-maxstreams-config

Conversation

@VWang1111

Copy link
Copy Markdown
Contributor

Summary

  • Configure NettyNioAsyncHttpClient with Http2Configuration.maxStreams(1L) to force one bidirectional stream per TCP connection
  • Set maxConcurrency(500) to support up to 500 simultaneous connections in the shared pool
  • Explicitly set Protocol.HTTP2

Problem

Without explicit HTTP/2 configuration, the AWS SDK multiplexes all bidirectional streams over a small number of TCP connections (~2x CPU cores). For real-time audio streaming, this causes streams to starve each other -- audio chunks queue behind other streams' data in Netty's HTTP/2 multiplexer, leading to backpressure overflow and transcription failures under concurrent load.

Validation

Load tested with 400 concurrent bidirectional streams against a single SageMaker endpoint:

  • With fix: 400/400 active, 6.9k transcripts in 5 min, 0 errors, 0 retries
  • Without fix: 0 transcripts -- all streams starve each other

Backwards Compatibility

Callers needing custom HTTP/2 settings can still use the existing SageMakerTransportFactory(config, smClient) constructor with a pre-configured client.

Test plan

  • Single connection smoke test -- 12 transcripts, 0 errors
  • 400 concurrent connections -- 0 errors, 0 retries, transcripts flowing
  • Existing constructor for custom clients still compiles

🤖 Generated with Claude Code

Without explicit HTTP/2 configuration, the AWS SDK multiplexes all
bidirectional streams over a small number of TCP connections (~2x CPU
cores). For real-time audio streaming, this causes streams to starve
each other -- audio chunks queue behind other streams' data in Netty's
HTTP/2 multiplexer, leading to backpressure overflow and transcription
failures under concurrent load.

Configure NettyNioAsyncHttpClient with:
- maxStreams(1): one bidirectional stream per TCP connection, ensuring
  each stream's audio data flows without contention
- maxConcurrency(500): allow up to 500 simultaneous TCP connections
  in the shared pool
- protocol(HTTP2): explicitly set (was implicit via the SDK)

Validated with a load test sustaining 400 concurrent bidi streams
(0 errors, 0 retries). Without this fix, the same test produces
0 successful transcriptions due to stream starvation.

Callers needing custom HTTP/2 settings can still use the existing
SageMakerTransportFactory(config, smClient) constructor with a
pre-configured client.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@VWang1111 VWang1111 requested a review from lukeocodes as a code owner April 13, 2026 19:33
@VWang1111 VWang1111 merged commit da68ffc into main Apr 13, 2026
7 checks passed
lukeocodes added a commit that referenced this pull request Apr 13, 2026
🤖 I have created a release *beep* *boop*
---


##
[0.1.1](v0.1.0...v0.1.1)
(2026-04-13)


### Bug Fixes

* configure HTTP/2 maxStreams=1 to prevent bidi stream starvation
([29dc4b8](29dc4b8))
* configure HTTP/2 maxStreams=1 to prevent bidi stream starvation
([#10](#10))
([da68ffc](da68ffc))

---
This PR was generated with [Release
Please](https://github.com/googleapis/release-please). See
[documentation](https://github.com/googleapis/release-please#release-please).
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.

3 participants