Consider the following program:
package main
import "fmt"
func main() {
fmt.Println("Hello World!")
}
If I build this on my Linux AMD64 machine (Go 1.9), like this:
$ go build
$ ls -la helloworld
-rwxr-xr-x 1 janf group 2029206 Sep 11 16:58 helloworld
I get a a binary that is about 2 Mb in size.
The reason for this (which has been explained in other answers) is that we are using the "fmt" package which is quite large, but the binary has also not been stripped and this means that the symbol table is still there. If we instead instruct the compiler to strip the binary, it will become much smaller:
$ go build -ldflags "-s -w"
$ ls -la helloworld
-rwxr-xr-x 1 janf group 1323616 Sep 11 17:01 helloworld
However, if we rewrite the program to use the builtin function print, instead of fmt.Println, like this:
package main
func main() {
print("Hello World!\n")
}
And then compile it:
$ go build -ldflags "-s -w"
$ ls -la helloworld
-rwxr-xr-x 1 janf group 714176 Sep 11 17:06 helloworld
We end up with an even smaller binary. This is as small as we can get it without resorting to tricks like UPX-packing, so the overhead of the Go-runtime is roughly 700 Kb.