Understanding Go Environment Variables
If you’ve worked with Go, you’ve likely used the go env command. While it may seem technical, understanding these settings is key to mastering Go's toolchain. It's more than just a way to print configuration values, it gives insight into how the Go toolchain works behind the scenes.
When I was new to Go, I had to set up my first project. A senior developer shared her
go envsettings with me, and everything worked. But later, I wanted to understand what those values meant and how they impacted my development environment. For anyone new to Go, this guide will explain the most important environment variables, what they do, and when you should care.
What is go env?
The go env command displays environment variables used by the Go toolchain. It helps you understand your current Go setup and how it's configured.
go envExample output
GO111MODULE="on"
GOPATH="/Users/you/go"
GOPROXY="https://proxy.golang.org,direct"
GOSUMDB="sum.golang.org"You can also query a specific variable
go env GOMODCACHEKey Environment Variables
GOPATH
Before Go modules were introduced, GOPATH defined the workspace for Go code, where your source code, compiled binaries, and packages were stored.
By default, GOPATH points to a directory like ~/go (on Unix-based systems) or %USERPROFILE%\go (on Windows). Inside this path, you’ll typically see
src: Source code for your projects and third-party packagespkg: Compiled package files (.a files), used to speed up buildsbin: Compiled executables built withgo install
For example, after running
go get github.com/someuser/libraryThe source code might end up in
~/go/src/github.com/someuser/libraryNote: Although Go modules have mostly replaced GOPATH based workflows,
GOPATHis still used as a fallback for things like storing downloaded tools or binaries.
GO111MODULE
When Go was released in 2009, it didn’t have a built-in dependency manager. Developers fetched code using go get, and everything was stored in $GOPATH/src. There was no versioning, the latest commit on master was used by default.
Go modules, introduced in Go 1.11, solved these issues by introducing a new system with versioning and reproducible builds.
GO111MODULE controls how and when Go uses modules
GO111MODULE=off: Disables module mode. Go uses GOPATH.GO111MODULE=on: Forces module mode, usinggo.mod.GO111MODULE=auto: Enables module mode if ago.modfile is present otherwise, falls back to GOPATH.
Since Go 1.16, module mode is the default, making GO111MODULE rarely needed
GOMODCACHE
This is the directory where Go stores downloaded module dependencies. It speeds up builds by avoiding repeated downloads of the same modules.
go env GOMODCACHEThis cache works alongside GOCACHE to optimize build performance.
GOPROXY
By default, Go downloads modules directly from their version control systems (VCS). However, the GOPROXY environment variable lets you configure a proxy server to manage this.
Get Dilan Dashintha’s stories in your inbox
Join Medium for free to get updates from this writer.
Using a Go module proxy provides several benefits
- Caching: Dependencies are stored forever.
- No vendor folder: Saves repo space.
- Immutable storage: Prevents tampering or deletion.
- No VCS required: Dependencies are served over HTTP.
- Faster builds: Parallel fetching of
.zipandgo.modfiles. - Custom proxy support: You can run your own Go proxy for more control.
The default proxy is
https://proxy.golang.orgTo disable the proxy
GOPROXY=directGONOPROXY
GONOPROXY is an environment variable that specifies which module paths should not be fetched through the proxy defined in GOPROXY.
This is useful when you’re working with private repositories or internal modules that shouldn’t be accessed via public Go module proxies.
It accepts a comma-separated list of glob patterns (module path prefixes). These patterns tell the Go command to bypass the module proxy for matching modules and fetch them directly from the source.
GOSUMDB
Go modules include checksums to ensure the code you download hasn’t been tampered with. These checksums are verified against a public checksum database (sum.golang.org by default).
Each module version gets two lines in your go.sum file
- One for the module’s code
- One for its
go.modfile
If the checksums don’t match what’s expected, the go command fails to protect you from tampered modules.
If a module is private or not listed in go.sum, Go checks the checksum database. This can be disabled or adjusted using the GONOSUMDB variable.
GOPRIVATE
If you’re using private/internal modules (e.g., from your company’s Git repo), Go may fail to fetch them because it tries to use the public proxy and checksum database.
GOPRIVATE tells Go to skip the public proxy and checksum database for specified module path patterns (e.g., corp.example.com/*).
Example
GOPRIVATE=github.com/myorg/*This is essential for working with private dependencies without 404 errors or checksum mismatches.
GONOSUMDB
This is similar to GOPRIVATE, but specifically disables checksum validation against the public database for specified modules.
If not set explicitly, it inherits the value from GOPRIVATE.
Use this when you trust your private modules and want to avoid validation errors during builds.
GOROOT
GOROOT points to the location of your Go installation (the Go SDK), including the standard library and compiler tools.
By default, it’s
/usr/local/goYou typically don’t need to set this unless you’re using a custom Go installation.
Check it with
go env GOROOTGOOS and GOARCH
These control the target OS and CPU architecture for your build.
GOOS:linux,windows,darwinetc.GOARCH:amd64,arm64etc.
Example: build a binary for Linux on macOS
GOOS=linux GOARCH=amd64 go buildGOCACHE
This variable points to the directory used for build caching. When you run go build or go test, intermediate results are stored here. If nothing changes in your code, Go can reuse the cache for faster builds.
Summary
Go environment variables play a crucial role in how your development environment is configured. Whether you’re managing dependencies, working with private modules, or optimizing build performance, understanding these variables helps you write more efficient and reliable Go code.








