I'm looking to create a minimal statically linked (using musl) native-image Clojure build. My one-liner hello world app with zero dependencies currently weighs in at 17 MB (5MB with UPX). How can I shrink it more?
@borkdude is expert on doing that
(I'm including --enable-http here because I'll need it eventually – without that flag the resulting build is 13MB)
Since it's just a hello world, probably there is nothing that much to improve on clojure side
(oh and I'm using https://github.com/clj-easy/graal-build-time)
https://github.com/borkdude/dynaload may be a good lib to consider depending on how much your code increase
(and -Dclojure.compiler.direct-linking=true)
yeah, thanks
I think this is about the size you can expect from a clojure based image
clojure-lsp adds
-H:ServiceLoaderFeatureExcludeServices=javax.sound.sampled.spi.AudioFileReader \
-H:ServiceLoaderFeatureExcludeServices=javax.sound.midi.spi.MidiFileReader \
-H:ServiceLoaderFeatureExcludeServices=javax.sound.sampled.spi.MixerProvider \
-H:ServiceLoaderFeatureExcludeServices=javax.sound.sampled.spi.FormatConversionProvider \
-H:ServiceLoaderFeatureExcludeServices=javax.sound.sampled.spi.AudioFileWriter \
-H:ServiceLoaderFeatureExcludeServices=javax.sound.midi.spi.MidiDeviceProvider \
-H:ServiceLoaderFeatureExcludeServices=javax.sound.midi.spi.SoundbankReader \
-H:ServiceLoaderFeatureExcludeServices=javax.sound.midi.spi.MidiFileWriter
to remove some unused stuff, but TBH I don't remember if that is worth/if affects that much the sizehmm okay
I think that was copied from bb
and is probably not necessary
yeah, doesn't seem to make a difference
guess I'll write this thing in Rust instead 🙂
what kind of thing is it?
a utility that I'm packaging as a container, and that I need to be as small as possible to reduce latency when downloading it
is 10mb going to make a difference? zipped 5mb?
babashka installs in 0s on github actions and it's 25mb zipped or so (75 unzipped)
a reduction in size with upx doesn't even outweigh the smaller download, since the download is already zipped
and upx adds to the start time since it unzips the binary on every startup
Is this something that is intended to be run as a lambda?
you can also write lambdas with #nbb - just a couple of lines
They just have a new Node 18 runner. ARM runners are the fastest especially when you choose more memory
it's for something more like a backend for running lambdas
every MB counts
I could make sure to load it upfront of course, in which case it wouldn't be that big a deal
yeah in that case rust or go might make sense
if its the download latency youre worried about, id go with #nbb or layer in the binary in the runtime
but might as well go for smaller size so I can download it when I need it
or ... zig! :)
ive used https://docs.aws.amazon.com/lambda/latest/dg/configuration-layers.html for fat binaries before
thanks! 🙂
Also I think now you can also have ram loaded preemptively into AWS Lambda, so that startup time can become really minimal. I have not checked it out, but https://docs.aws.amazon.com/lambda/latest/dg/snapstart.html?icmpid=docs_lambda_rss
There's also tools that compress your exe and decompress and run them at runtime, like UPX and gzexe https://upx.github.io/ https://linux.die.net/man/1/gzexe
I'm aware of those tools but they affect startup time negatively
FWIW, upx was mentioned in the original message of this thread