Search code examples
springperformancespring-bootcontrollerresponse

Spring boot rest controller pretty slow repsonse


Hello stack overflow community. I am using Spring boot and it is working just fine for me, but when it comes to "large" datasets it gets pretty slow, let me show you an example code:

@GetMapping("/get/some/example/data/{lines}")
public ResponseEntity<String> getTestData(@PathVariable("lines") long lines) {
    StringBuilder stringBuilder = new StringBuilder();

    for(int i=0; i<lines; i++){
      stringBuilder.append("...very long string here...");
    }
    return ResponseEntity.ok(stringBuilder.toString());
  }

Ok, what you see is just a pretty simple rest controller to generate dynamic sized responses. Imagine the string in stringBuilder.append() is 500 characters and more.

Now lets call this endpoint with the browser and watch the result with DevTools(F12) of chrome:

Response Headers:

Content-Encoding: gzip

Content-Type: text/html;charset=UTF-8

Transfer-Encoding: chunked

vary: accept-encoding


Call endpoint for line = 100:

  • 419 KB Resources
  • Finish 377 ms (+- 50ms...)

Call endpoint for line = 1000:

  • 3.0 MB Resources
  • Finish 2108000ms (+- 3000ms)

Lets compare those results. OK the resource size is not exact 10 times more, because of the gzip compression. But my problem is the response time. It takes 377ms and 210800ms for 10 times more data. This means it takes 559 times more time for 10 times more data.

You can see there is no DB connection, no complicated code at all. The for loop with 1000 iterations takes less than 5ms, so the problem is behind the scene itself or in the HTTP. Can you pls help me understand, why large sets of data does effect the performance so much. And can you pls help to find a solution to improve the response time.

In addition, you can see the mime type "Content-Type: text/html" in headers, when this is changed to application/json it is faster but still not fast.

See also the request headers here: Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,/;q=0.8,application/signed-exchange;v=b3;q=0.9

Accept-Encoding: gzip, deflate, br

Accept-Language: de-DE,de;q=0.9,es-VE;q=0.8,es;q=0.7,en-US;q=0.6,en;q=0.5

Cache-Control: no-cache

Connection: keep-alive

Host: localhost:8080

Pragma: no-cache

Sec-Fetch-Mode: navigate

Sec-Fetch-Site: none

Sec-Fetch-User: ?1

Upgrade-Insecure-Requests: 1

User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko)

Chrome/79.0.3945.130 Safari/537.36


dependencies:

<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.9.RELEASE</version>

<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>5.2.0.RELEASE</version>

...

I am pretty thankful for any hints and suggestions.


Solution

  • I just figured out there is no performance issue at all. I just installed Postman to check if it is the same there. No it isn't, Postman and also the Firefox DevTools told me it is pretty fast. For some reason my favorite browser chrome was slowing it down for large data. Believe me or not, the same request on firefox and chrome for a reponse of 14.41 MB takes around 223 ms on firefox and on chrome around 23000 ms... But this is only with open build tools, so when you are watching