Search code examples
javawindowshttptcpundertow

What is the limiting factor of HTTP requests per seconds when running "empty" Undertow?


I'm running a very simplistic Undertow configuration. Whole code included:

public class HelloWorldUndertow {
    public static void main(String[] args) {
        Undertow undertow = Undertow.builder()
                .addHttpListener(9090, "0.0.0.0")
                .setHandler(new HttpHandler() {
                    @Override
                    public void handleRequest(HttpServerExchange exchange) throws Exception {
                        exchange.setResponseCode(200);
                        exchange.getResponseSender().send("hello!");
                    }
                }).build();
        undertow.start();
    }
}

I try to test how many requests per second it can handle. I'm using apache ab tool for measurements:

ab -n 100000 -c 10 http://localhost:9090/test

The biggest number I managed to get is around 10000 3/sec:

Concurrency Level:      10
    Time taken for tests:   10.664 seconds
    Complete requests:      100000
    Failed requests:        0
    Total transferred:      10000000 bytes
    HTML transferred:       600000 bytes
    Requests per second:    9377.69 [#/sec] (mean)
    Time per request:       1.066 [ms] (mean)
    Time per request:       0.107 [ms] (mean, across all concurrent requests)
    Transfer rate:          915.79 [Kbytes/sec] received

    Connection Times (ms)
    min  mean[+/-sd] median   max
    Connect:        0    0   0.2      0       1
    Processing:     0    1   0.5      1      11
    Waiting:        0    1   0.5      1      11
    Total:          0    1   0.5      1      11

    Percentage of the requests served within a certain time (ms)
    50%      1
    66%      1
    75%      1
    80%      1
    90%      2
    95%      2
    98%      2
    99%      2
    100%     11 (longest request)

I get that it is BIG, but I'm curoius what is a limiting factor in this case. It's not processor (the app is running below 20% when sampled using Java Mission Control) and not memory. I'm running it on Windows - maybe that is the reason?


Solution

  • I can't tell you how to make it perform better when running in Windows, but if you run it in Linux you can do the tuning recommended for Jetty here: https://eclipse.dev/jetty/documentation/jetty-9/index.html#high-load

    In summary:

    sysctl -w net.core.rmem_max=16777216
    sysctl -w net.core.wmem_max=16777216
    sysctl -w net.ipv4.tcp_rmem="4096 87380 16777216"
    sysctl -w net.ipv4.tcp_wmem="4096 16384 16777216"
    sysctl -w net.core.somaxconn=4096
    sysctl -w net.core.netdev_max_backlog=16384
    sysctl -w net.ipv4.tcp_max_syn_backlog=8192
    sysctl -w net.ipv4.tcp_syncookies=1
    sysctl -w net.ipv4.ip_local_port_range="1024 65535"
    sysctl -w net.ipv4.tcp_tw_recycle=1
    sysctl -w net.ipv4.tcp_congestion_control=cubic
    

    Include the -server JVM param when you run your code.

    Then try: ab -n 100000 -c 100 http://localhost:9090/test

    (make 100,000 requests using 100 connections)

    When I try that in a Linux VM running in VMware Player on my Windows 7 laptop (3 years old) I get over 100,000 requests per second.