eclipse-vertx / eclipse-vertx/vert.x
Large HTTP/2 request bodies (gRPC 10MB+) are extremely slow
- Dominant language
- Java
- Stars
- 14.7k
- Forks
- 2.1k
- Avg merge
- 1d 10h
- Merged PRs (30d)
- 27
Description
### Version
5.0.0
### Context
### Describe the bug
When serving large payloads over HTTP/2 (e.g. gRPC unary RPC with 10MB+ messages), requests are extremely slow or appear to hang. The server-side handler may not be invoked until the full body slowly trickles in.
This affects applications using Vert.x HTTP server + vertx-grpc unified mode (same port as HTTP). Legacy gRPC-Java/Netty server with a larger flow-control window completes the same workload in ~1s vs ~25s+ with Vert.x HTTP/2.
Related Quarkus issue: https://github.com/quarkusio/quarkus/issues/48526
### Root cause (investigation)
The default HTTP/2 connection window is too small for large messages:
1. **`Http2ServerConfig.java`** — `connectionWindowSize` defaults to `-1`:
- `vertx-core/src/main/java/io/vertx/core/http/Http2ServerConfig.java:38`
2. **`HttpServerOptions.java`** — `DEFAULT_HTTP2_CONNECTION_WINDOW_SIZE = -1`:
- `vertx-core/src/main/java/io/vertx/core/http/HttpServerOptions.java:127`
3. **`Http2Settings.java`** — stream initial window = **65535 bytes (64KB)**:
- `vertx-core/src/main/java/io/vertx/core/http/Http2Settings.java:56`
4. **`HttpServerConnectionHandler.java`** — larger window is only applied when `connectionWindowSize > 0`:
- `vertx-core/src/main/java/io/vertx/core/http/impl/tcp/HttpServerConnectionHandler.java:92-94`
- With default `-1`, `setWindowSize()` is never called.
5. **Flow-control path** — WINDOW_UPDATE only after app consumes bytes:
- `DefaultHttp2Stream.java:91-94` → `Http2ConnectionImpl.java:464-469` → `VertxHttp2ConnectionHandler.java:274-278`
With a 64KB window, a 10MB message requires hundreds of WINDOW_UPDATE round-trips before the application receives the full body.
Contributor guide
Research direction
Start with Http2ServerConfig.java, HttpServerOptions.java, and Http2Settings.java, then trace the connection and flow-control paths through HttpServerConnectionHandler.java, DefaultHttp2Stream.java, Http2ConnectionImpl.java, and VertxHttp2ConnectionHandler.java. Reproduce the 10MB+ HTTP/2 request and determine the appropriate window behavior; done means the handler receives the request without the reported multi-second stall.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- grpc, java
- Domain
- api, backend, networking
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 55/100