JDK-8158690 : GET request via HTTP/2 has a huge delays due to Nagle���s Algorithm and Delayed ACK clash
  • Type: Bug
  • Component: core-libs
  • Sub-Component: java.net
  • Affected Version: 9
  • Priority: P2
  • Status: Resolved
  • Resolution: Fixed
  • OS: linux,os_x
  • CPU: generic
  • Submitted: 2016-06-05
  • Updated: 2017-06-28
  • Resolved: 2016-06-24
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
9 b125Fixed
Related Reports
Relates :  
HttpClient has a poor performance with HTTP/2 get requests on Linux platforms. Benchmark is able to perform 25 requests/sec. At the same moment alternative Jetty HTTP/2 client produces up to ~9000 requests per seconds.
Similar issue is on MacOSX (490 requests per second).
There is no issue on Solaris & Windows.

Analysis has shown that the problem is TCP Nagle���s Algorithm and Delayed ACK clash. Like described here: http://www.stuartcheshire.org/papers/NagleDelayedAck/

To confirm, this issue is platform agnostic from the clients point of view, right? It is dependent on the server doing TCP delayed acknowledgments. So I can remove the OS/CPU labels.

draft benchmarks are available at http://cr.openjdk.java.net/~skuksenko/jep110/benchmarks/draft.00/

I am not 100% sure that which should set "setTcpNoDelay(true)" for all cases. Maybe more reasonable will be provide HttpClient API to settings that.

Simple patch (Setting setTcpNoDelay(true) on socket): --- a/src/java.httpclient/share/classes/java/net/http/PlainHttpConnection.java Tue May 31 13:10:46 2016 +0530 +++ b/src/java.httpclient/share/classes/java/net/http/PlainHttpConnection.java Sat Jun 04 17:58:01 2016 -0700 @@ -128,6 +128,7 @@ this.chan = SocketChannel.open(); int bufsize = client.getReceiveBufferSize(); chan.setOption(StandardSocketOptions.SO_RCVBUF, bufsize); + chan.socket().setTcpNoDelay(true); } catch (IOException e) { throw new InternalError(e); } --------------- it solves the issue. After that HttpClient is able to make 6000 GET requests per second (via HTTP/2)