<!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>