Space Cat, Prince Among Thieves

Go Binary Sizes Are Growing out of Control

Update 2019-07-17: I have released a follow up post Go Binary Sizes Are Relatively Stable which speaks on what's happened in the time since this was published.

Note: This is not intended as a "Go Sucks" post. I love Go. I am not saying the developers are lazy or dumb or any of the things Reddit has implied. I am not implying I could build a better compiler. Rob Pike and the Go team are geniuses whom I look up to. The tone of this was intended to be a light "man I wish binaries were smaller" but that is not how Reddit seemed to take it. Also, the title is hyperbole and not meant to literally mean no one has control over it.

I started toying with Go about two years ago before the 1.0 release. I love the language, it meets me in a comfortable place between C and a scripting languages like PHP. I find it fun to write and an easy way to bust out performant code quickly. The binaries for a simple Hello, 世界 were large though, around 55KB. I figured this was something the Go team would work out later; it is a lot of space just to send a string to standard out.

With the release of Go 1.0 though, I noticed the binary size had grown slightly to 242KB. Discouraging but livable. I was quite hopeful with the 1.1 release, but it had actually nearly doubled in size coming out to a whopping 405KB. Then this morning I compiled it again in the newly release 1.2 and to my horror the ever simple program came out to 557KB.

What on earth is going on in that binary? I am no expert on compilers but I would imagine the vast majority of what is in there is completely unnecessary and could be optimized out. Changing the script to "Hello, World" rather than Go's flaunted unicode version has zero effect on binary size, as one would expect but I was hopeful.

For reference the complete source of my Hello, 世界 follows. Using fmt comes out even larger.

package main

func main() {
    println("Hello, 世界")
}

Here is a collection of binaries compiled in different versions of Go. Notice how imgavg grows from 1.9MB to 3.7MB. My applications are all small tools. I can only imagine the effect this has an already large application.

Golang binary sizes grow with each release

I really hope something is done about this. I would love to see tiny (<32KB) binaries from Go but right now that doesn't seem to be a priority for them. The fact that Hello, 世界 fills half a floppy means the language is not be useful for lighter or embedded environments.

As noted in the header there is an addendum to this:


Comment by: ahm on

ahm's Gravatar The Go devs are aware of the issue:

https://code.google.com/p/go/issues/detail?id=6853

Comment by: Thibaut Colar on

Thibaut Colar's Gravatar For that size you get a fully standalone binary (including the garbage collector, the scheduling system and more) so really that's actually tiny if you compare that to a PHP program pus it's large interpreter.

If you really care about the size that much, then you could probably dynamically link the program (instead of statically), but I've never bothered to do that.

Comment by: Terry A. Davis on

Terry A. Davis's Gravatar In TempleOS, you do not have OBJ or EXE files. Kernel.BIN and Compiler.BIN are the only binary files. File sizes are shockingly small, shockingly small.

Comment by: Michael Szegedy on

Michael Szegedy's Gravatar Wouldn't interpreting them make them slow though?

Comment by: Random Stranger on

Random Stranger's Gravatar You get a full compiler, garbage collector, coroutine-based cooperative multithreading, FFI interface and the fastest JIT for a scripting language in measly 460KB - try LuaJIT. Compared to it, current Go binaries are really really fat...

Comment by: Name on

Name's Gravatar That's not the point, the point is that it grew so significantly. Before you got all the features for half the size.

Comment by: NoName on

NoName's Gravatar Use upx
https://github.com/pwaller/goupx/

Comment by: Tyler Mace on

Tyler Mace's Gravatar We needn't worry about smaller executable sizes when floppy space is so cheap.

Comment by: Linker on

Linker's Gravatar Go binaries are statically linked. Compare it to statically linked binaries produced by other modern tool chains.

Comment by: James Henstridge on

James Henstridge's Gravatar If you are happy to deploy a dynamically linked binary, then it is reasonable to compare Go's static binaries to the dynamic binaries from other languages. Until Go's reference compiler can produce dynamic binaries, you can't very well compare dynamic to dynamic.

Comment by: Dave Cheney on

Dave Cheney's Gravatar Yup, we know it's an issue and it will improve when 1.3 ships.

Go binaries are always going to be larger that the same *simple* program written in C because almost all the C functions are provided by libc.so at runtime.

As many posters have already pointed out, once your Go application starts to *do* something, like talk to the network using TLS or talk to a database, sure the Go binary size increases, but comparable to the same program written in C with _all the included libraries compiled statically_.

Finally, please don't strip your binaries; it isn't supported, isn't tested and is known to produce broken executables.

If you have a problem with the previous statement, the correct place to request this is golang.org/issue.

Comment by: Martin on

Martin's Gravatar Don't complain, on Windows they're 8MEGS! And you know what? I still don't care.
Because: The size of executables of small programs doesn't matter, because small programs are only examples or test code. And as soon as your program gets meaningful big and complex go's binaries don't get much bigger (maybe 1-2MB on Win). And as long as we don't talk about 20MB+ you're still small than every Java application...

Comment by: Ahmed on

Ahmed's Gravatar you can try to remove the debug information , if you using Unix base system( BSD,linux,Mac) complie using the flage s like this example:
go build -ldflags "-s" hello.o

Comment by: Smithb163 on

Smithb163's Gravatar Hey very nice web site!! Man.. Beautiful.. Wonderful.. I'll bookmark your web site and take the feeds alsoKI am satisfied to seek out a lot of helpful information here in the publish, we want work out extra techniques in this regard, thank you for sharing gddedcaggdebbbge

Comment by: MC on

MC's Gravatar Half a floppy? How much paper tape does that work out to?

Comment by: carlok on

carlok's Gravatar Floppies ? Paper tapes ? Consider yourselves lucky bastards; for legacy reasons we still have to use clay tablets at our place. We have strict weight limits in place, for example the run-time libraries of a prog. lang. must be under 1 ton of fired clay to be admissible).

On other note, we are currently seeking experts to integrate parts of our infrastructure using hieroglyphics and cuneiform respectively. Generous salary (choice of babylonian or egyptian tetradrachms), senior developers are issued personal slaves !!!

Comment by: Timofey on

Timofey's Gravatar See https://github.com/rekby/multiex
It help to contain many small go-programs in a binaries with only one overload by libraries size.
It is good for a lot of small utilities.

Comment by: kdeenanauth on

kdeenanauth's Gravatar In case someone finds their way here again - there are new options for tinier executables: https://blog.filippo.io/shrink-your-go-binaries-with-this-one-weird-trick/

Comment by: Larf on

Larf's Gravatar It's a C based language it's expected to grow in size!

Email address will never be publicly visible.

Basic HTML allowed.