Hello Josiah,
In my previous mail, I mentioned an incorrect system property to
configure for the timeout. The right one is
"jdk.httpclient.quic.idleTimeout". This one too takes a value in
seconds. So configuring it to "-Djdk.httpclient.quic.idleTimeout=50"
(for example) would be useful in the application code you are
experimenting with. Let us know how it works out.
-Jaikiran
On 10/11/25 7:31 pm, Jaikiran Pai wrote:
Looking at the application code, the relevant parts appear to be this:
ServerConnectionConfig.builder()
.maxIdleTimeoutInSeconds(50)
...
new Http3ApplicationProtocolFactory(
(request, response) -> {
try {
Thread.sleep(Duration.ofSeconds(40));
} catch (InterruptedException e) {
Thread.interrupted();
}
response.setStatus(200);
...
HttpClient.newBuilder()
.version(Version.valueOf("HTTP_3"))
.sslContext(sslContext)
.build()
.send(
HttpRequest.newBuilder()
.timeout(Duration.ofSeconds(45))
.uri(URI.create("https://localhost:8080"))
.GET()
The server is configured to have a QUIC idle timeout of 50 seconds. On
the client side, the JDK's HttpClient for HTTP/3 by default uses a
idle timeout of 30 seconds. These timeouts translate to the QUIC
connection level idle timeouts, which decide when to terminate the
connection if there's no UDP traffic on that connection. The QUIC RFC
specifies that each of the endpoints (the server and the client) can
choose to advertise a idle timeout of their own, but the negotiated
idle timeout will always be the lower of those two and that negotiated
timeout must be honoured by both sides of the connection. So in this
case, the server advertises 50 seconds and the client advertises 30
seconds, so the 30 second timeout is the negotiated one for this
connection and thus if the connection doesn't generate any traffic for
that duration (like in this case), it gets idle terminated.
The default idle timeout for JDK's HttpClient can be configured using
the "jdk.httpclient.keepalive.timeout.h3" system property
https://download.java.net/java/early_access/jdk26/docs/api/java.net.http/module-summary.html.
So setting it to -Djdk.httpclient.keepalive.timeout.h3=50 (for
example), should then allow your application to stay idle without
generating any UDP traffic for the QUIC connection for that long.
-Jaikiran
On 10/11/25 7:08 pm, Josiah Noel wrote:
To emulate a few of my worst case latency scenarios that I have seen
in production, I have added a sleep with a thirty second timer before
I send a 200 status.
Once more I have attached my jbang script as well as the extended
logs when I ran with
-Djdk.httpclient.HttpClient.log=requests,headers,errors,http3,quic:control:retransmit.
--
Cheers, Josiah.