<!DOCTYPE html><html><head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
</head>
<body>
<p>Hello Josiah,</p>
<p>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.</p>
<p>-Jaikiran<br>
</p>
<div class="moz-cite-prefix">On 10/11/25 7:31 pm, Jaikiran Pai
wrote:<br>
</div>
<blockquote type="cite" cite="mid:cea1235b-5641-4e9f-b68c-a5180aa55684@oracle.com">
<p>Looking at the application code, the relevant parts appear to
be this:<br>
<br>
ServerConnectionConfig.builder()<br>
.maxIdleTimeoutInSeconds(50)<br>
...<br>
new Http3ApplicationProtocolFactory(<br>
(request, response) -> {<br>
try {<br>
Thread.sleep(Duration.ofSeconds(40));<br>
} catch (InterruptedException e) {<br>
Thread.interrupted();<br>
}<br>
response.setStatus(200);<br>
...<br>
HttpClient.newBuilder()<br>
.version(Version.valueOf("HTTP_3"))<br>
.sslContext(sslContext)<br>
.build()<br>
.send(<br>
HttpRequest.newBuilder()<br>
.timeout(Duration.ofSeconds(45))<br>
.uri(URI.create(<a class="moz-txt-link-rfc2396E" href="https://localhost:8080" moz-do-not-send="true">"https://localhost:8080"</a>))<br>
.GET()<br>
<br>
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.<br>
<br>
The default idle timeout for JDK's HttpClient can be configured
using the "jdk.httpclient.keepalive.timeout.h3" system property
<a class="moz-txt-link-freetext" href="https://download.java.net/java/early_access/jdk26/docs/api/java.net.http/module-summary.html" moz-do-not-send="true">https://download.java.net/java/early_access/jdk26/docs/api/java.net.http/module-summary.html</a>.
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.<br>
<br>
-Jaikiran<br>
</p>
<div class="moz-cite-prefix">On 10/11/25 7:08 pm, Josiah Noel
wrote:<br>
</div>
<blockquote type="cite" cite="mid:CAJ_t5UZmcA8+e5AGbMx9ctBt=GfZS4ea-1qzF=tAmLSRGLTH7w@mail.gmail.com">
<div dir="ltr">
<div>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.</div>
<div><br>
</div>
<div>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.</div>
<span class="gmail_signature_prefix">-- </span><br>
<div dir="ltr" class="gmail_signature" data-smartmail="gmail_signature">
<div dir="ltr">Cheers, Josiah.</div>
</div>
<input name="virtru-metadata" type="hidden" value="{"email-policy":{"state":"closed","expirationUnit":"days","disableCopyPaste":false,"disablePrint":false,"disableForwarding":false,"enableNoauth":false,"persistentProtection":false,"expandedWatermarking":false,"expires":false,"isManaged":false,"sms":false},"attachments":{},"compose-id":"1","compose-window":{"secure":false}}"></div>
</blockquote>
</blockquote>
</body>
</html>