Go Binary Sizes Are Relatively Stable

Almost six years ago I wrote an unintentionally inflammatory post I'd wrongly imagined no one would read: Go Binary Sizes Are Growing out of Control. I had noticed my binaries getting larger and larger as I upgraded versions of Go and wanted to express my frustration.

Much has changed since then; there have been ten major releases of Go in that time.

I was curious how much this had changed since my post went out. I realized I could use Docker to easily automate the process of compiling against all the major releases of Go. The exact code I used is on GitHub.

I hit a couple of hurdles. First, the oldest official version of Go on Docker Hub is 1.2 - which happens to be the version my previous post left off. Secondly, a number of the programs I'd previously compared no longer compiled in such old versions of Go.

As I didn't want to bother sifting through old versions of projects or manually dealing with old versions of Go I decided to make this more of a standalone comparison than a direct continuation of the previous post.

I ended up going through most of my Go projects to find what would actually compile in ancient versions of Go.

The tools I compiled for the comparison are in order hello world using fmt , hello world using println, Hookah - a tool for GitHub automation, imgavg - a tool for averaging a collection of images, and sqlread - a tool for querying MySQL dumps without loading them into a database.

The Results

Without further ado, the raw data in megabytes.

binary 1.2 1.3 1.4 1.5 1.6 1.7 1.8 1.9 1.10 1.11 1.12 hello 2.240 1.824 1.941 2.367 2.288 1.634 1.552 1.860 2.012 1.907 1.997 hello-nofmt 0.577 0.475 0.635 1.076 1.101 1.003 0.960 1.035 1.086 1.068 1.127 hookah 8.362 6.749 6.880 7.692 8.747 6.396 6.558 6.810 7.320 7.286 8.239 imgavg 3.724 2.997 3.042 3.564 3.512 2.706 2.508 2.626 2.816 2.732 2.848 sqlread 4.878 3.748 3.837 4.349 4.232 3.184 3.057 3.109 3.306 3.150 3.304

You can see from the trendlines that for the majority of the projects there has been a small downtick in size overall. The 1.5 and 1.6 releases causing a pretty universal uptick which 1.7 seems to have quickly mitigated.

Curiously Hookah shows by far the most fluctuation in size by a pretty large margin. This is increasingly curious because comparing recursive dependencies the only builtin packages Hookah uses that sqlread does not are regexp and regexp/syntax , whereas sqlread itself actually utilizes a pretty large number more. This to me indicates it's variation is probably deeper than just changes to the built in libraries but more to do with the compilation output and optimization itself.

Everything except for the simplest Hello World "hello-nofmt" has shown an overall decrease. On the other hand hello-nofmt which boils down to println("Hello, 世界") plus boilerplate has shown an overall 550kb increase. This clearly illustrates the flucution and growth in size of the compiled runtime.

Conclusion

Go binaries are not "growing out of control". They're pretty stable overall and for the most part have shown a decrease.

All said and done however they are still larger than I would like. I'm hopeful things like tree shaking will help improve this in the future. There is certainly cause for hope with WASM becoming a major compilation target size will matter more than ever as it will directly affect load times.