Skip to content

Massive performance drop when retrieving InputStream using REST client #48755

@LarsSven

Description

@LarsSven

Describe the bug

We were working on moving some code over from a non-Quarkus REST client to a Quarkus REST client. We noticed a massive drop in performance when we dit that, and got some very interesting results.

When using the Quarkus client to download a file from a URL as an InputStream, the creation of the InputStream object (So not actually streaming the file, but the creation of the InputStream) scales worse than linearly with the size of the file you are downloading. Getting the InputStream however should take a constant amount of time and be milliseconds of work.

We ran a test against a set of object sizes we uploaded to MinIO (and thus the REST client simply sees a download link for the file):

1 * 1024,          // 1KB
1 * 1024 * 1024,   // 1MB
10 * 1024 * 1024,  // 10MB
100 * 1024 * 1024, // 100MB
250 * 1024 * 1024, // 250MB
500 * 1024 * 1024, // 500MB
1L * 1024 * 1024 * 1024 // 1GB

The default REST client produced these results:

Downloading resource_1024_bytes_14840480614219054265.bin using Default REST client
Time to generate InputStream: 27 ms
Time to stream to file: 0 ms
Downloading resource_1048576_bytes_13817578619309500621.bin using Default REST client
Time to generate InputStream: 3 ms
Time to stream to file: 3 ms
Downloading resource_10485760_bytes_2310616242777621351.bin using Default REST client
Time to generate InputStream: 1 ms
Time to stream to file: 22 ms
Downloading resource_104857600_bytes_8607201645369659057.bin using Default REST client
Time to generate InputStream: 2 ms
Time to stream to file: 114 ms
Downloading resource_262144000_bytes_8533175391852326467.bin using Default REST client
Time to generate InputStream: 3 ms
Time to stream to file: 248 ms
Downloading resource_524288000_bytes_16558373151874773264.bin using Default REST client
Time to generate InputStream: 2 ms
Time to stream to file: 346 ms
Downloading resource_1073741824_bytes_14053281376256782222.bin using Default REST client
Time to generate InputStream: 2 ms
Time to stream to file: 686 ms

The Quarkus REST client however produced these results:

Downloading resource_1024_bytes_14840480614219054265.bin using Quarkus REST client
Time to generate InputStream: 68 ms
Time to stream to file: 0 ms
Downloading resource_1048576_bytes_13817578619309500621.bin using Quarkus REST client
Time to generate InputStream: 5 ms
Time to stream to file: 0 ms
Downloading resource_10485760_bytes_2310616242777621351.bin using Quarkus REST client
Time to generate InputStream: 16 ms
Time to stream to file: 3 ms
Downloading resource_104857600_bytes_8607201645369659057.bin using Quarkus REST client
Time to generate InputStream: 234 ms
Time to stream to file: 28 ms
Downloading resource_262144000_bytes_8533175391852326467.bin using Quarkus REST client
Time to generate InputStream: 1123 ms
Time to stream to file: 69 ms
Downloading resource_524288000_bytes_16558373151874773264.bin using Quarkus REST client
Time to generate InputStream: 3837 ms
Time to stream to file: 136 ms
Downloading resource_1073741824_bytes_14053281376256782222.bin using Quarkus REST client
Time to generate InputStream: 15140 ms
Time to stream to file: 268 ms

Expected behavior

Generating the InputStream should take a few milliseconds and stay constant no matter how much data needs to be streamed

Actual behavior

The InputStream generation scales with a time complexity that is worse than linear and takes over 15 seconds to create the InputStream for a 1GB file.

How to Reproduce?

  1. Clone the reproducer: https://gitlab.com/l.s.andringa1/quarkus-inputstream-reproducer
  2. Run ./gradlew quarkusRun

Output of uname -a or ver

Ubuntu 25.04

Output of java -version

Java 21.0.7

Quarkus version or git rev

3.24.2

Build tool (ie. output of mvnw --version or gradlew --version)

Gradle 8.14.2

Additional information

No response

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions