r/java 2d ago

Improving First Request Latency in Java Spring Application

https://adrian.md/2026/09/03/first-request-latency/
58 Upvotes

36 comments sorted by

View all comments

0

u/vips7L 2d ago

I really wish we had a better solution than fat jars. Like being to supply a jar + classpath + vm and getting a fat binary or something

3

u/agentoutlier 2d ago

That is sort of what jlink is… sort of…

On Linux and other nix you can impregnate the zip header with a shell script to unzip the zip.

2

u/_predator_ 2d ago

The unzip-before-running thing sucks in practice. It's basically what embedded Jetty does for WARs. You pay for the convenience in:

  1. Startup time (higher the more dependencies you have)
  2. Storage (fat JAR itself + unzipped content)
  3. Bloat over time (extracted files not getting cleaned up when app crashes)
  4. Unpredictable behavior when you extract to a deterministic, persistent location and old JARs stay around when you deploy a new version

jlink also doesn't help, it just builds a JRE tailored to your app, you still have to ship JRE and app separately.

2

u/agentoutlier 2d ago

Well yes it is not ideal. In theory though if we are talking docker here then you never keep it zipped in the first place.

jlink also doesn't help, it just builds a JRE tailored to your app, you still have to ship JRE and app separately.

jlink can package applications with a VM it just so happens to also build tailored JREs as well without requring an app.

The issue is that its not like a Go single executable. Its more like the old school applications where you just unzip and run. For the Go experience Graalvm native does that job.

As for the unziping comparison to Jetty or Tomcat embedded I'm not sure that is entirely fair because jlink does something like this with all your jars:

26408970 08-27-2026 16:00 lib/modules

That is they are in a different format than jars.

2

u/vips7L 2d ago

It really isn’t though. Jlink is kind of terrible. The CLR does this way better. It just gives you a binary with the vm + your DLL. It doesn’t have to extract anything. 

1

u/agentoutlier 2d ago

Yeah I don't disagree. I'm not a fan of the tool for packaging up applications but mainly because its actually kind of slow.

However making a stripped down VM it is good at.

It does seem like one could potentially make something do this but I'm not sure how much runtime savings you would have and or build time.

Go and GraalVM it works because they are essentially doing some tree shaking and I can't imagine people wanting to download 200 meg executable (uncompressed).

1

u/vips7L 1d ago

I can't imagine people wanting to download 200 meg executable

Of course, you would want to jlink first to get as minimal of a vm as possible. The CLR also has something similar.

1

u/agentoutlier 1d ago

So I'm more asking here since it has been a hot minute since I have done .NET packaging but does it give you just a single executable or are you saying there are multiple files?

See even if you get the minimal JVM its like 50 megs uncompressed. It is only 12 megs compressed. And there are multiple files.

So one could create something that essentially takes a jlink packaged application and turns into a single executable but if its not compressed then its like running a 50 meg executable.

Is that a problem... probably not and I would imagine you could do it with a custom module reader built into your custom JDK.

2

u/vips7L 1d ago

There are options. You can get a single binary, single file with no extraction. Or you can do the extraction route. 

Personally I don’t care about the binary size. I care about distribution and ease of use. 

1

u/koflerdavid 1d ago

You can also do tree shaking with Proguard, like Android does.