How Do I Set Up a Go Dev Environment in a Cloud Sandbox?
Updated October 27, 2026 .md
Short answer: A new sandbox has Go 1.27.2 in /usr/local/go. Installing the current release from go.dev took 3 seconds. Modules cache in ~/go/pkg/mod and builds in ~/.cache/go-build, both on the sandbox disk, so a named snapshot cut a cold 87-second build of the GitHub CLI to 4.6 seconds.
We ran every command on this page on prod on 2026-10-27 in eu-central, on small sandboxes (2 vCPU, 4 GB) and one default (4 vCPU, 8 GB) for the size comparison. Timings vary by host and neighbors. The project is cli/cli, the GitHub CLI, at commit 9be5608: about 400 MB of modules and 259 test packages, so the caches matter.
Results#
| Step | small |
default |
|---|---|---|
| Install Go 1.27.3 from go.dev | 2.7 s | |
go build ./cmd/gh, empty module and build cache |
87.4 s | |
go build, warm module cache, empty build cache (2 runs) |
63.2, 63.3 s | 38.3, 35.2 s |
go build, nothing changed |
0.3 s | |
go build, one file changed |
3.1 s | |
go test ./..., first run |
155 s | |
go test ./..., again (results cached) |
1.5 s | |
go test -count=1 ./..., warm build cache |
93.8 s | |
Cross-compile gh for another OS/arch (3 targets) |
65 to 69 s each | |
From the named snapshot: first go build |
4.6 s | |
From the named snapshot: go test ./... |
3.1 s (257 of 259 cached) |
The lesson: in Go the build cache is worth more than the module cache. Downloading modules was about 24 of the 87 cold seconds; compiling was the rest. Save both, and a new sandbox builds in seconds.
1. Check the Go that is already there#
sbx new --name go-dev --type small
sbx exec sb_qvmfxnvkgt bash -lc "go version; which go; go env GOROOT GOPATH GOCACHE GOMODCACHE GOTOOLCHAIN; nproc"go version go1.27.2 linux/amd64
/usr/local/go/bin/go
/usr/local/go
/home/user/go
/home/user/.cache/go-build
/home/user/go/pkg/mod
auto
2Go comes from the official tarball in /usr/local/go, not from apt. Both caches start empty and live under /home/user. That was the image on 2026-10-27; it changes over time. The full inventory is in What's pre-installed in a sandbox.
2. Watch GOTOOLCHAIN=auto, then install the current release#
cli/cli's go.mod says toolchain go1.27.3. With the default GOTOOLCHAIN=auto, the first go command in the repo fetched that toolchain by itself:
sbx exec sb_qvmfxnvkgt --timeout 300 bash -lc "git clone -q https://github.com/cli/cli && cd cli && git checkout -q 9be5608274ec && go version"go: downloading go1.27.3 (linux/amd64)
go version go1.27.3 linux/amd64That works, but the toolchain lands in the module cache, and every repo that pins a newer Go repeats it. Installing the release itself is cleaner. The current stable release on go.dev/dl on 2026-10-27 was go1.27.3. Check the SHA-256 from that page, then replace /usr/local/go as the official install steps say:
sbx exec sb_qvmfxnvkgt --timeout 300 bash -lc '
curl -fsSLO https://go.dev/dl/go1.27.3.linux-amd64.tar.gz
echo "65efbc80fdc1fa2cd2631cad5b481777a68e8725f34e89f50fc6ac714e379b40 go1.27.3.linux-amd64.tar.gz" | sha256sum -c -
sudo rm -rf /usr/local/go && sudo tar -C /usr/local -xzf go1.27.3.linux-amd64.tar.gz
go version; cd cli && GOTOOLCHAIN=local go version
go clean -modcache'go1.27.3.linux-amd64.tar.gz: OK
go version go1.27.3 linux/amd64
go version go1.27.3 linux/amd64It took 2.7 seconds. GOTOOLCHAIN=local go version proves the repo now builds with the installed Go and no download. go clean -modcache removed the auto-fetched toolchain so the next measurements start cold.
3. Build and test, cold and warm#
Long builds run past the 30-second default of sbx exec, so we ran them with --detach and read the log. The script times each step with bash time:
sbx exec sb_qvmfxnvkgt --detach "bash -l bench1.sh > bench1.log 2>&1"
sbx exec sb_qvmfxnvkgt "cat bench1.log"== build, empty mod + build cache
87.416 s
394M /home/user/go/pkg/mod
555M /home/user/.cache/go-build
== build, warm mod cache, empty build cache
63.240 s
== build, nothing changed
0.339 s
== build, one file in pkg/cmd/pr/create changed
3.114 sThe second build ran after go clean -cache, so it shows the cost of compiling with every module already on disk. Then the tests:
== go test ./..., first run
155.026 s
exit 0
…
go: downloading github.com/creack/pty v1.1.24
go: downloading gopkg.in/h2non/gock.v1 v1.1.2
…
== go test ./..., second run (results cached)
1.487 s
== go test -count=1 ./..., warm build cache
93.822 s
exit 0
396M /home/user/go/pkg/mod
857M /home/user/.cache/go-buildAll 259 test packages passed. Two details matter for snapshots:
- The first test run downloaded eight more modules. They are test-only dependencies that
go build ./cmd/ghnever needs. Rungo mod downloador the full test suite before you save, or the snapshot misses them. go testcaches passing results, so an unchanged package reports(cached).-count=1forces the tests to run; it still reuses compiled packages.
4. Cross-compile and copy the binary out#
Go builds for any OS and CPU from the sandbox. With CGO_ENABLED=0 no C toolchain is involved:
cd ~/cli
for os_arch in darwin/arm64 windows/amd64 linux/arm64; do
GOOS=${os_arch%/*} GOARCH=${os_arch#*/}
out=dist/gh-$GOOS-$GOARCH; [ $GOOS = windows ] && out=$out.exe
CGO_ENABLED=0 GOOS=$GOOS GOARCH=$GOARCH go build -trimpath -ldflags "-s -w" -o $out ./cmd/gh
done
file dist/*dist/gh-darwin-arm64: Mach-O 64-bit arm64 executable, flags:<|DYLDLINK|PIE>
dist/gh-linux-arm64: ELF 64-bit LSB executable, ARM aarch64, version 1 (SYSV), statically linked, …
dist/gh-windows-amd64.exe: PE32+ executable (console) x86-64, for MS Windows, 8 sectionsEach target took 65 to 69 seconds on small. The build cache is keyed by target, so the first build for a new GOOS/GOARCH is a cold build even when the native one is warm. Copy a binary to your machine with sbx scp:
sbx scp sb_qvmfxnvkgt:/home/user/cli/dist/gh-darwin-arm64 .
sha256sum gh-darwin-arm64a3bda216ea135c3de256488eab31ec2ecd36a116cc155c6ddf453426ab9cfe21 gh-darwin-arm64The 38 MB file arrived in 22 seconds with the same hash as in the sandbox. We checked the file type, not a run on a Mac.
5. gopls over SSH#
Install the language server in the sandbox. It goes to ~/go/bin, which the login PATH already includes:
sbx exec sb_qvmfxnvkgt --timeout 600 bash -lc "go install golang.org/x/tools/gopls@latest && gopls version"golang.org/x/tools/gopls v0.24.0The install took 36 seconds. With sbx ssh-config --install done once on your laptop, we added a type error to a file and asked gopls about it over SSH:
ssh sb_qvmfxnvkgt.sbx 'bash -lc "cd cli && gopls check pkg/cmd/pr/create/create.go"'/home/user/cli/pkg/cmd/pr/create/create.go:1404:28-31: cannot use "x" (untyped string constant) as int value in return statementSo gopls runs in the sandbox against its module and build caches. In VS Code or Cursor, connect with Remote-SSH to sb_qvmfxnvkgt.sbx, open /home/user/cli and install the Go extension on the remote side; it looks for gopls on that PATH. We tested gopls check over SSH, not the editor UI. Setup and troubleshooting for the editors are in SSH into a cloud sandbox from VS Code or Cursor.
6. Save it as a named snapshot and start from it#
sbx snapshot sb_qvmfxnvkgt go-cache
sbx new --name go-dev-2 --type small --from go-cacheThe save took 2.1 seconds and the new sandbox was ready in 3.2 seconds. The snapshot holds the whole disk: Go 1.27.3 in /usr/local/go, the clone, both caches and gopls. In the new sandbox:
go version go1.27.3 linux/amd64
/home/user/go/bin/gopls
== build, as saved
4.642 s
== go test ./..., as saved
3.121 s
exit 0
257
== go test -count=1 ./..., as saved
98.650 s
== build, module cache only (go clean -cache)
63.315 sThe first build took 4.6 seconds instead of 87. Go still hashed every input to confirm the cache was valid. 257 of 259 test packages came back (cached). With only the module cache (after go clean -cache), the build took 63 seconds, the same as in the original sandbox. To name the snapshot by a hash of go.sum and rebuild it when dependencies change, follow Cache dependencies in a named snapshot.
7. Small or default for builds#
We started a default sandbox from the same snapshot (--type default; a larger size than the snapshot works) and timed the compile with a warm module cache and an empty build cache:
4
== build, module cache only, run 1
38.331 s
== build, module cache only, run 2
35.168 sThat is about 37 seconds on 4 vCPU against 63 on 2 vCPU: 1.7 times faster at twice the vCPUs. The Go compiler builds packages in parallel, so cold builds scale with cores, while a warm build is a few seconds on either size. How each size does on a plain CPU benchmark is in CPU performance by sandbox size.
FAQ#
Which Go version does a Sandboxer sandbox have?#
On 2026-10-27, Go 1.27.2 from the official tarball in /usr/local/go. The image is updated over time, so check go version. With GOTOOLCHAIN=auto, a repo that pins a newer toolchain downloads it on first use.
Where are GOCACHE and GOMODCACHE in a sandbox?#
GOCACHE is /home/user/.cache/go-build and GOMODCACHE is /home/user/go/pkg/mod. Both are on the sandbox disk, so they survive sbx stop and are saved in a named snapshot or a fork.
Do I need to snapshot the build cache, or only the modules?#
Save both. For the GitHub CLI on small, modules alone took a build from 87 to 63 seconds; with the build cache it took 4.6 seconds. Together they used about 1.25 GB.
Can I build binaries for macOS or Windows in a sandbox?#
Yes, for pure Go code. Set GOOS, GOARCH and CGO_ENABLED=0, then copy the result out with sbx scp. Code that needs cgo also needs a C cross-compiler for the target.
Should I use small or default for Go builds?#
A cold build of the GitHub CLI took 63 seconds on small and about 37 on default. If you start from a snapshot with a warm build cache, small builds in seconds.
Related#
More guides
For running AI-written code we rank Sandboxer, Freestyle and E2B first: each gives code its own VM with an API or SDK and can pause with memory. Pick Daytona for Windows or GPUs, Modal or Northflank for GPUs at scale, E2B or Northflank to run in your own cloud, and Vercel Sandbox if your app lives on Vercel.
For coding agents we rank Sandboxer first: a full Ubuntu VM with Claude Code and Codex preinstalled, Docker, and stop-and-resume that keeps the agent's session in memory. Freestyle and Amp Orbs also keep memory across pauses. Pick E2B for prebuilt agent templates on open source, Docker Sandboxes for free local runs, and Codespaces if you live in GitHub.
The best Daytona alternatives depend on why you're switching. For a full Linux microVM on every sandbox with memory-saving stop and Docker, we rank Sandboxer first. E2B suits open source and self-hosting, Modal massive short-job fleets, Northflank bring-your-own-cloud with GPUs, and Vercel Sandbox apps on Vercel.
If you're leaving E2B for longer sessions or a fuller machine, we rank Sandboxer first, then Freestyle: both give each sandbox a full Linux VM that keeps memory across pauses, with Docker and no short session cap. Pick Daytona for Windows or GPUs, Northflank for bring-your-own-cloud, and stay on E2B if you need open source.